Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
0831382d
Commit
0831382d
authored
Jun 15, 2012
by
Alexander Belopolsky
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue #15006: Allow equality comparison between naive and aware time
or datetime objects.
parent
ea0b8239
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
56 additions
and
19 deletions
+56
-19
Doc/library/datetime.rst
Doc/library/datetime.rst
+18
-2
Lib/datetime.py
Lib/datetime.py
+14
-8
Lib/test/datetimetester.py
Lib/test/datetimetester.py
+6
-6
Misc/NEWS
Misc/NEWS
+2
-3
Modules/_datetimemodule.c
Modules/_datetimemodule.c
+16
-0
No files found.
Doc/library/datetime.rst
View file @
0831382d
...
...
@@ -901,13 +901,21 @@ Supported operations:
*datetime1* is considered less than *datetime2* when *datetime1* precedes
*datetime2* in time.
If one comparand is naive and the other is aware, :exc:`TypeError` is raised.
If one comparand is naive and the other is aware, :exc:`TypeError`
is raised if an order comparison is attempted. For equality
comparisons, naive instances are never equal to aware instances.
If both comparands are aware, and have the same :attr:`tzinfo` attribute, the
common :attr:`tzinfo` attribute is ignored and the base datetimes are
compared. If both comparands are aware and have different :attr:`tzinfo`
attributes, the comparands are first adjusted by subtracting their UTC
offsets (obtained from ``self.utcoffset()``).
.. versionchanged:: 3.3
Equality comparisons between naive and aware :class:`datetime`
instances don't raise :exc:`TypeError`.
.. note::
In order to stop comparison from falling back to the default scheme of comparing
...
...
@@ -1316,7 +1324,10 @@ Supported operations:
* comparison of :class:`.time` to :class:`.time`, where *a* is considered less
than *b* when *a* precedes *b* in time. If one comparand is naive and the other
is aware, :exc:`TypeError` is raised. If both comparands are aware, and have
is aware, :exc:`TypeError` is raised if an order comparison is attempted. For equality
comparisons, naive instances are never equal to aware instances.
If both comparands are aware, and have
the same :attr:`tzinfo` attribute, the common :attr:`tzinfo` attribute is
ignored and the base times are compared. If both comparands are aware and
have different :attr:`tzinfo` attributes, the comparands are first adjusted by
...
...
@@ -1326,6 +1337,11 @@ Supported operations:
different type, :exc:`TypeError` is raised unless the comparison is ``==`` or
``!=``. The latter cases return :const:`False` or :const:`True`, respectively.
.. versionchanged:: 3.3
Equality comparisons between naive and aware :class:`time` instances
don't raise :exc:`TypeError`.
* hash, use as dict key
* efficient pickling
...
...
Lib/datetime.py
View file @
0831382d
...
...
@@ -1065,13 +1065,13 @@ class time:
def
__eq__
(
self
,
other
):
if
isinstance
(
other
,
time
):
return
self
.
_cmp
(
other
)
==
0
return
self
.
_cmp
(
other
,
allow_mixed
=
True
)
==
0
else
:
return
False
def
__ne__
(
self
,
other
):
if
isinstance
(
other
,
time
):
return
self
.
_cmp
(
other
)
!=
0
return
self
.
_cmp
(
other
,
allow_mixed
=
True
)
!=
0
else
:
return
True
...
...
@@ -1099,7 +1099,7 @@ class time:
else
:
_cmperror
(
self
,
other
)
def
_cmp
(
self
,
other
):
def
_cmp
(
self
,
other
,
allow_mixed
=
False
):
assert
isinstance
(
other
,
time
)
mytz
=
self
.
_tzinfo
ottz
=
other
.
_tzinfo
...
...
@@ -1118,7 +1118,10 @@ class time:
(
other
.
_hour
,
other
.
_minute
,
other
.
_second
,
other
.
_microsecond
))
if
myoff
is
None
or
otoff
is
None
:
raise
TypeError
(
"cannot compare naive and aware times"
)
if
allow_mixed
:
return
2
# arbitrary non-zero value
else
:
raise
TypeError
(
"cannot compare naive and aware times"
)
myhhmm
=
self
.
_hour
*
60
+
self
.
_minute
-
myoff
//
timedelta
(
minutes
=
1
)
othhmm
=
other
.
_hour
*
60
+
other
.
_minute
-
otoff
//
timedelta
(
minutes
=
1
)
return
_cmp
((
myhhmm
,
self
.
_second
,
self
.
_microsecond
),
...
...
@@ -1615,7 +1618,7 @@ class datetime(date):
def
__eq__
(
self
,
other
):
if
isinstance
(
other
,
datetime
):
return
self
.
_cmp
(
other
)
==
0
return
self
.
_cmp
(
other
,
allow_mixed
=
True
)
==
0
elif
not
isinstance
(
other
,
date
):
return
NotImplemented
else
:
...
...
@@ -1623,7 +1626,7 @@ class datetime(date):
def
__ne__
(
self
,
other
):
if
isinstance
(
other
,
datetime
):
return
self
.
_cmp
(
other
)
!=
0
return
self
.
_cmp
(
other
,
allow_mixed
=
True
)
!=
0
elif
not
isinstance
(
other
,
date
):
return
NotImplemented
else
:
...
...
@@ -1661,7 +1664,7 @@ class datetime(date):
else
:
_cmperror
(
self
,
other
)
def
_cmp
(
self
,
other
):
def
_cmp
(
self
,
other
,
allow_mixed
=
False
):
assert
isinstance
(
other
,
datetime
)
mytz
=
self
.
_tzinfo
ottz
=
other
.
_tzinfo
...
...
@@ -1682,7 +1685,10 @@ class datetime(date):
other
.
_hour
,
other
.
_minute
,
other
.
_second
,
other
.
_microsecond
))
if
myoff
is
None
or
otoff
is
None
:
raise
TypeError
(
"cannot compare naive and aware datetimes"
)
if
allow_mixed
:
return
2
# arbitrary non-zero value
else
:
raise
TypeError
(
"cannot compare naive and aware datetimes"
)
# XXX What follows could be done more efficiently...
diff
=
self
-
other
# this will take offsets into account
if
diff
.
days
<
0
:
...
...
Lib/test/datetimetester.py
View file @
0831382d
...
...
@@ -2544,7 +2544,7 @@ class TestTimeTZ(TestTime, TZInfoBase, unittest.TestCase):
self
.
assertEqual
(
t1
,
t2
)
self
.
assertEqual
(
t1
,
t3
)
self
.
assertEqual
(
t2
,
t3
)
self
.
assert
Raises
(
TypeError
,
lambda
:
t4
==
t5
)
# mixed tz-aware & naive
self
.
assert
NotEqual
(
t4
,
t5
)
# mixed tz-aware & naive
self
.
assertRaises
(
TypeError
,
lambda
:
t4
<
t5
)
# mixed tz-aware & naive
self
.
assertRaises
(
TypeError
,
lambda
:
t5
<
t4
)
# mixed tz-aware & naive
...
...
@@ -2696,7 +2696,7 @@ class TestTimeTZ(TestTime, TZInfoBase, unittest.TestCase):
t2
=
t2
.
replace
(
tzinfo
=
FixedOffset
(
None
,
""
))
self
.
assertEqual
(
t1
,
t2
)
t2
=
t2
.
replace
(
tzinfo
=
FixedOffset
(
0
,
""
))
self
.
assert
Raises
(
TypeError
,
lambda
:
t1
==
t2
)
self
.
assert
NotEqual
(
t1
,
t2
)
# In time w/ identical tzinfo objects, utcoffset is ignored.
class
Varies
(
tzinfo
):
...
...
@@ -2801,16 +2801,16 @@ class TestDateTimeTZ(TestDateTime, TZInfoBase, unittest.TestCase):
microsecond
=
1
)
self
.
assertTrue
(
t1
>
t2
)
# Make t2 naive and it should
fail
.
# Make t2 naive and it should
differ
.
t2
=
self
.
theclass
.
min
self
.
assert
Raises
(
TypeError
,
lambda
:
t1
==
t2
)
self
.
assert
NotEqual
(
t1
,
t2
)
self
.
assertEqual
(
t2
,
t2
)
# It's also naive if it has tzinfo but tzinfo.utcoffset() is None.
class
Naive
(
tzinfo
):
def
utcoffset
(
self
,
dt
):
return
None
t2
=
self
.
theclass
(
5
,
6
,
7
,
tzinfo
=
Naive
())
self
.
assert
Raises
(
TypeError
,
lambda
:
t1
==
t2
)
self
.
assert
NotEqual
(
t1
,
t2
)
self
.
assertEqual
(
t2
,
t2
)
# OTOH, it's OK to compare two of these mixing the two ways of being
...
...
@@ -3327,7 +3327,7 @@ class TestDateTimeTZ(TestDateTime, TZInfoBase, unittest.TestCase):
t2
=
t2
.
replace
(
tzinfo
=
FixedOffset
(
None
,
""
))
self
.
assertEqual
(
t1
,
t2
)
t2
=
t2
.
replace
(
tzinfo
=
FixedOffset
(
0
,
""
))
self
.
assert
Raises
(
TypeError
,
lambda
:
t1
==
t2
)
self
.
assert
NotEqual
(
t1
,
t2
)
# In datetime w/ identical tzinfo objects, utcoffset is ignored.
class
Varies
(
tzinfo
):
...
...
Misc/NEWS
View file @
0831382d
...
...
@@ -24,9 +24,8 @@ Core and Builtins
Library
-------
- Issue #14938: importlib.abc.SourceLoader.is_package() will not consider a
module whose name ends in '
__init__
' a package (e.g. importing pkg.__init__
directly should be considered a module, not a package).
- Issue #15006: Allow equality comparison between naive and aware
time or datetime objects.
- Issue #14982: Document that pkgutil'
s
iteration
functions
require
the
non
-
standard
iter_modules
()
method
to
be
defined
by
an
importer
(
something
...
...
Modules/_datetimemodule.c
View file @
0831382d
...
...
@@ -3707,6 +3707,14 @@ time_richcompare(PyObject *self, PyObject *other, int op)
TIME_GET_MICROSECOND
(
other
);
result
=
diff_to_bool
(
diff
,
op
);
}
else
if
(
op
==
Py_EQ
)
{
result
=
Py_False
;
Py_INCREF
(
result
);
}
else
if
(
op
==
Py_NE
)
{
result
=
Py_True
;
Py_INCREF
(
result
);
}
else
{
PyErr_SetString
(
PyExc_TypeError
,
"can't compare offset-naive and "
...
...
@@ -4584,6 +4592,14 @@ datetime_richcompare(PyObject *self, PyObject *other, int op)
Py_DECREF
(
delta
);
result
=
diff_to_bool
(
diff
,
op
);
}
else
if
(
op
==
Py_EQ
)
{
result
=
Py_False
;
Py_INCREF
(
result
);
}
else
if
(
op
==
Py_NE
)
{
result
=
Py_True
;
Py_INCREF
(
result
);
}
else
{
PyErr_SetString
(
PyExc_TypeError
,
"can't compare offset-naive and "
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment