Skip to content

BUG: NA with binary operation with bytes #49155

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 17, 2022
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions doc/source/whatsnew/v2.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ Missing
^^^^^^^
- Bug in :meth:`Index.equals` raising ``TypeError`` when :class:`Index` consists of tuples that contain ``NA`` (:issue:`48446`)
- Bug in :meth:`Series.map` caused incorrect result when data has NaNs and defaultdict mapping was used (:issue:`48813`)
- Bug in :class:`NA` raising a ``TypeError`` instead of return :class:`NA` when performing a binary operation with a ``bytes`` object (:issue:`49108`)

MultiIndex
^^^^^^^^^^
Expand Down
2 changes: 1 addition & 1 deletion pandas/_libs/missing.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ def is_numeric_na(values: ndarray) -> ndarray:
def _create_binary_propagating_op(name, is_divmod=False):

def method(self, other):
if (other is C_NA or isinstance(other, str)
if (other is C_NA or isinstance(other, (str, bytes))
or isinstance(other, (numbers.Number, np.bool_))
or util.is_array(other) and not other.shape):
# Need the other.shape clause to handle NumPy scalars,
Expand Down
49 changes: 21 additions & 28 deletions pandas/tests/scalar/test_na_scalar.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,36 +49,29 @@ def test_hashable():
assert d[NA] == "test"


def test_arithmetic_ops(all_arithmetic_functions):
@pytest.mark.parametrize(
"other", [NA, 1, 1.0, "a", b"a", np.int64(1), np.nan], ids=repr
)
def test_arithmetic_ops(all_arithmetic_functions, other):
op = all_arithmetic_functions

for other in [NA, 1, 1.0, "a", np.int64(1), np.nan]:
if op.__name__ in ("pow", "rpow", "rmod") and isinstance(other, str):
continue
if op.__name__ in ("divmod", "rdivmod"):
assert op(NA, other) is (NA, NA)
else:
if op.__name__ == "rpow":
# avoid special case
other += 1
assert op(NA, other) is NA


def test_comparison_ops():

for other in [NA, 1, 1.0, "a", np.int64(1), np.nan, np.bool_(True)]:
assert (NA == other) is NA
assert (NA != other) is NA
assert (NA > other) is NA
assert (NA >= other) is NA
assert (NA < other) is NA
assert (NA <= other) is NA
assert (other == NA) is NA
assert (other != NA) is NA
assert (other > NA) is NA
assert (other >= NA) is NA
assert (other < NA) is NA
assert (other <= NA) is NA
if op.__name__ in ("pow", "rpow", "rmod") and isinstance(other, (str, bytes)):
pytest.skip(reason=f"{op.__name__} with NA and {other} not defined.")
if op.__name__ in ("divmod", "rdivmod"):
assert op(NA, other) is (NA, NA)
else:
if op.__name__ == "rpow":
# avoid special case
other += 1
assert op(NA, other) is NA


@pytest.mark.parametrize(
"other", [NA, 1, 1.0, "a", b"a", np.int64(1), np.nan, np.bool_(True)]
)
def test_comparison_ops(comparison_op, other):
assert comparison_op(NA, other) is NA
assert comparison_op(other, NA) is NA


@pytest.mark.parametrize(
Expand Down