Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions doc/source/whatsnew/v0.25.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ Backwards incompatible API changes

.. _whatsnew_0250.api_breaking.utc_offset_indexing:

- Comparing :class:`~Timestamp.Timestamp` with unsupported objects now returns ``NotImplemented`` instead of raising ``TypeError``. This implies that unsupported rich comparisons are delegated to the other object, and is now consistent with Python 3 behavior for ``datetime`` objects (:issue:`24011`)


Indexing with date strings with UTC offsets
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Expand Down
17 changes: 2 additions & 15 deletions pandas/_libs/tslibs/timestamps.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -239,26 +239,13 @@ cdef class _Timestamp(datetime):
if is_datetime64_object(other):
other = Timestamp(other)
else:
if op == Py_EQ:
return False
elif op == Py_NE:
return True

# only allow ==, != ops
raise TypeError('Cannot compare type %r with type %r' %
(type(self).__name__,
type(other).__name__))
return NotImplemented
elif is_array(other):
# avoid recursion error GH#15183
return PyObject_RichCompare(np.array([self]), other, op)
return PyObject_RichCompare(other, self, reverse_ops[op])
else:
if op == Py_EQ:
return False
elif op == Py_NE:
return True
raise TypeError('Cannot compare type %r with type %r' %
(type(self).__name__, type(other).__name__))
return NotImplemented

self._assert_tzawareness_compat(other)
return cmp_scalar(self.value, ots.value, op)
Expand Down
32 changes: 32 additions & 0 deletions pandas/tests/scalar/timestamp/test_comparisons.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,3 +166,35 @@ def test_timestamp_compare_with_early_datetime(self):
assert stamp >= datetime(1600, 1, 1)
assert stamp < datetime(2700, 1, 1)
assert stamp <= datetime(2700, 1, 1)


def test_rich_comparison_with_unsupported_type():
# Comparisons with unsupported objects should return NotImplemented
# (it previously raised TypeError)

class Inf(object):
def __lt__(self, o):
return False

def __le__(self, o):
return isinstance(o, Inf)

def __gt__(self, o):
return not isinstance(o, Inf)

def __ge__(self, o):
return True

def __eq__(self, o):
return isinstance(o, Inf)

inf = Inf()
timestamp = Timestamp('2018-11-30')

for left, right in [(inf, timestamp), (timestamp, inf)]:
assert left > right or right < left
assert left >= right or right <= left
assert not (left == right)
assert left != right