Skip to content

Commit b3cb072

Browse files
committed
Merge pull request #4970 from jreback/invalid_compare
API: raise a TypeError on invalid comparison ops on Series (e.g. integer/datetime) GH4968
2 parents 275a42c + d76e988 commit b3cb072

File tree

4 files changed

+48
-1
lines changed

4 files changed

+48
-1
lines changed

doc/source/release.rst

+1
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ API Changes
225225
- moved timedeltas support to pandas.tseries.timedeltas.py; add timedeltas string parsing,
226226
add top-level ``to_timedelta`` function
227227
- ``NDFrame`` now is compatible with Python's toplevel ``abs()`` function (:issue:`4821`).
228+
- raise a ``TypeError`` on invalid comparison ops on Series/DataFrame (e.g. integer/datetime) (:issue:`4968`)
228229

229230
Internal Refactoring
230231
~~~~~~~~~~~~~~~~~~~~

pandas/core/series.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,13 @@ def na_op(x, y):
324324
else:
325325
result = lib.scalar_compare(x, y, op)
326326
else:
327-
result = op(x, y)
327+
328+
try:
329+
result = getattr(x,name)(y)
330+
if result is NotImplemented:
331+
raise TypeError("invalid type comparison")
332+
except (AttributeError):
333+
result = op(x, y)
328334

329335
return result
330336

pandas/tests/test_frame.py

+25
Original file line numberDiff line numberDiff line change
@@ -4296,6 +4296,31 @@ def test_operators_none_as_na(self):
42964296
result = op(df.fillna(7), df)
42974297
assert_frame_equal(result, expected)
42984298

4299+
def test_comparison_invalid(self):
4300+
4301+
def check(df,df2):
4302+
4303+
for (x, y) in [(df,df2),(df2,df)]:
4304+
self.assertRaises(TypeError, lambda : x == y)
4305+
self.assertRaises(TypeError, lambda : x != y)
4306+
self.assertRaises(TypeError, lambda : x >= y)
4307+
self.assertRaises(TypeError, lambda : x > y)
4308+
self.assertRaises(TypeError, lambda : x < y)
4309+
self.assertRaises(TypeError, lambda : x <= y)
4310+
4311+
# GH4968
4312+
# invalid date/int comparisons
4313+
df = DataFrame(np.random.randint(10, size=(10, 1)), columns=['a'])
4314+
df['dates'] = date_range('20010101', periods=len(df))
4315+
4316+
df2 = df.copy()
4317+
df2['dates'] = df['a']
4318+
check(df,df2)
4319+
4320+
df = DataFrame(np.random.randint(10, size=(10, 2)), columns=['a', 'b'])
4321+
df2 = DataFrame({'a': date_range('20010101', periods=len(df)), 'b': date_range('20100101', periods=len(df))})
4322+
check(df,df2)
4323+
42994324
def test_modulo(self):
43004325

43014326
# GH3590, modulo as ints

pandas/tests/test_series.py

+15
Original file line numberDiff line numberDiff line change
@@ -2663,6 +2663,21 @@ def test_comparison_object_numeric_nas(self):
26632663
expected = f(s.astype(float), shifted.astype(float))
26642664
assert_series_equal(result, expected)
26652665

2666+
def test_comparison_invalid(self):
2667+
2668+
# GH4968
2669+
# invalid date/int comparisons
2670+
s = Series(range(5))
2671+
s2 = Series(date_range('20010101', periods=5))
2672+
2673+
for (x, y) in [(s,s2),(s2,s)]:
2674+
self.assertRaises(TypeError, lambda : x == y)
2675+
self.assertRaises(TypeError, lambda : x != y)
2676+
self.assertRaises(TypeError, lambda : x >= y)
2677+
self.assertRaises(TypeError, lambda : x > y)
2678+
self.assertRaises(TypeError, lambda : x < y)
2679+
self.assertRaises(TypeError, lambda : x <= y)
2680+
26662681
def test_more_na_comparisons(self):
26672682
left = Series(['a', np.nan, 'c'])
26682683
right = Series(['a', np.nan, 'd'])

0 commit comments

Comments
 (0)