Skip to content

Commit cb827d8

Browse files
dsaxtonproost
authored andcommitted
BUG: Fix comparison between nullable int and string (pandas-dev#28945)
1 parent 64592a7 commit cb827d8

File tree

4 files changed

+46
-1
lines changed

4 files changed

+46
-1
lines changed

doc/source/whatsnew/v1.0.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -840,6 +840,7 @@ ExtensionArray
840840
^^^^^^^^^^^^^^
841841

842842
- Bug in :class:`arrays.PandasArray` when setting a scalar string (:issue:`28118`, :issue:`28150`).
843+
- Bug where nullable integers could not be compared to strings (:issue:`28930`)
843844
-
844845

845846

pandas/conftest.py

+18
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,24 @@ def any_int_dtype(request):
654654
return request.param
655655

656656

657+
@pytest.fixture(params=ALL_EA_INT_DTYPES)
658+
def any_nullable_int_dtype(request):
659+
"""
660+
Parameterized fixture for any nullable integer dtype.
661+
662+
* 'UInt8'
663+
* 'Int8'
664+
* 'UInt16'
665+
* 'Int16'
666+
* 'UInt32'
667+
* 'Int32'
668+
* 'UInt64'
669+
* 'Int64'
670+
"""
671+
672+
return request.param
673+
674+
657675
@pytest.fixture(params=ALL_REAL_DTYPES)
658676
def any_real_dtype(request):
659677
"""

pandas/core/arrays/integer.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
from pandas.core import nanops, ops
2727
from pandas.core.algorithms import take
2828
from pandas.core.arrays import ExtensionArray, ExtensionOpsMixin
29+
from pandas.core.ops import invalid_comparison
2930
from pandas.core.ops.common import unpack_zerodim_and_defer
3031
from pandas.core.tools.numeric import to_numeric
3132

@@ -646,7 +647,11 @@ def cmp_method(self, other):
646647
with warnings.catch_warnings():
647648
warnings.filterwarnings("ignore", "elementwise", FutureWarning)
648649
with np.errstate(all="ignore"):
649-
result = op(self._data, other)
650+
method = getattr(self._data, f"__{op_name}__")
651+
result = method(other)
652+
653+
if result is NotImplemented:
654+
result = invalid_comparison(self._data, other, op)
650655

651656
# nans propagate
652657
if mask is None:

pandas/tests/extension/test_integer.py

+21
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,27 @@ def check_opname(self, s, op_name, other, exc=None):
168168
def _compare_other(self, s, data, op_name, other):
169169
self.check_opname(s, op_name, other)
170170

171+
def test_compare_to_string(self, any_nullable_int_dtype):
172+
# GH 28930
173+
s = pd.Series([1, None], dtype=any_nullable_int_dtype)
174+
result = s == "a"
175+
expected = pd.Series([False, False])
176+
177+
self.assert_series_equal(result, expected)
178+
179+
def test_compare_to_int(self, any_nullable_int_dtype, all_compare_operators):
180+
# GH 28930
181+
s1 = pd.Series([1, 2, 3], dtype=any_nullable_int_dtype)
182+
s2 = pd.Series([1, 2, 3], dtype="int")
183+
184+
method = getattr(s1, all_compare_operators)
185+
result = method(2)
186+
187+
method = getattr(s2, all_compare_operators)
188+
expected = method(2)
189+
190+
self.assert_series_equal(result, expected)
191+
171192

172193
class TestInterface(base.BaseInterfaceTests):
173194
pass

0 commit comments

Comments
 (0)