Skip to content

Commit 48368ad

Browse files
authored
BUG: NA with binary operation with bytes (#49155)
1 parent f5a86fe commit 48368ad

File tree

3 files changed

+23
-29
lines changed

3 files changed

+23
-29
lines changed

doc/source/whatsnew/v2.0.0.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ Missing
230230
^^^^^^^
231231
- Bug in :meth:`Index.equals` raising ``TypeError`` when :class:`Index` consists of tuples that contain ``NA`` (:issue:`48446`)
232232
- Bug in :meth:`Series.map` caused incorrect result when data has NaNs and defaultdict mapping was used (:issue:`48813`)
233+
- Bug in :class:`NA` raising a ``TypeError`` instead of return :class:`NA` when performing a binary operation with a ``bytes`` object (:issue:`49108`)
233234

234235
MultiIndex
235236
^^^^^^^^^^

pandas/_libs/missing.pyx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ def is_numeric_na(values: ndarray) -> ndarray:
341341
def _create_binary_propagating_op(name, is_divmod=False):
342342

343343
def method(self, other):
344-
if (other is C_NA or isinstance(other, str)
344+
if (other is C_NA or isinstance(other, (str, bytes))
345345
or isinstance(other, (numbers.Number, np.bool_))
346346
or util.is_array(other) and not other.shape):
347347
# Need the other.shape clause to handle NumPy scalars,

pandas/tests/scalar/test_na_scalar.py

Lines changed: 21 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -49,36 +49,29 @@ def test_hashable():
4949
assert d[NA] == "test"
5050

5151

52-
def test_arithmetic_ops(all_arithmetic_functions):
52+
@pytest.mark.parametrize(
53+
"other", [NA, 1, 1.0, "a", b"a", np.int64(1), np.nan], ids=repr
54+
)
55+
def test_arithmetic_ops(all_arithmetic_functions, other):
5356
op = all_arithmetic_functions
5457

55-
for other in [NA, 1, 1.0, "a", np.int64(1), np.nan]:
56-
if op.__name__ in ("pow", "rpow", "rmod") and isinstance(other, str):
57-
continue
58-
if op.__name__ in ("divmod", "rdivmod"):
59-
assert op(NA, other) is (NA, NA)
60-
else:
61-
if op.__name__ == "rpow":
62-
# avoid special case
63-
other += 1
64-
assert op(NA, other) is NA
65-
66-
67-
def test_comparison_ops():
68-
69-
for other in [NA, 1, 1.0, "a", np.int64(1), np.nan, np.bool_(True)]:
70-
assert (NA == other) is NA
71-
assert (NA != other) is NA
72-
assert (NA > other) is NA
73-
assert (NA >= other) is NA
74-
assert (NA < other) is NA
75-
assert (NA <= other) is NA
76-
assert (other == NA) is NA
77-
assert (other != NA) is NA
78-
assert (other > NA) is NA
79-
assert (other >= NA) is NA
80-
assert (other < NA) is NA
81-
assert (other <= NA) is NA
58+
if op.__name__ in ("pow", "rpow", "rmod") and isinstance(other, (str, bytes)):
59+
pytest.skip(reason=f"{op.__name__} with NA and {other} not defined.")
60+
if op.__name__ in ("divmod", "rdivmod"):
61+
assert op(NA, other) is (NA, NA)
62+
else:
63+
if op.__name__ == "rpow":
64+
# avoid special case
65+
other += 1
66+
assert op(NA, other) is NA
67+
68+
69+
@pytest.mark.parametrize(
70+
"other", [NA, 1, 1.0, "a", b"a", np.int64(1), np.nan, np.bool_(True)]
71+
)
72+
def test_comparison_ops(comparison_op, other):
73+
assert comparison_op(NA, other) is NA
74+
assert comparison_op(other, NA) is NA
8275

8376

8477
@pytest.mark.parametrize(

0 commit comments

Comments
 (0)