Skip to content

Commit a329dc3

Browse files
authored
BUG: arithmetic with numpy-nullable vs pyarrow (#62647)
1 parent 5b10ba2 commit a329dc3

File tree

3 files changed

+36
-2
lines changed

3 files changed

+36
-2
lines changed

doc/source/whatsnew/v3.0.0.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,6 +1001,7 @@ Numeric
10011001
- Bug in :meth:`Series.dot` returning ``object`` dtype for :class:`ArrowDtype` and nullable-dtype data (:issue:`61375`)
10021002
- Bug in :meth:`Series.std` and :meth:`Series.var` when using complex-valued data (:issue:`61645`)
10031003
- Bug in ``np.matmul`` with :class:`Index` inputs raising a ``TypeError`` (:issue:`57079`)
1004+
- Bug in arithmetic operations between objects with numpy-nullable dtype and :class:`ArrowDtype` incorrectly raising (:issue:`58602`)
10041005

10051006
Conversion
10061007
^^^^^^^^^^

pandas/core/arrays/masked.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,10 @@
3737
is_string_dtype,
3838
pandas_dtype,
3939
)
40-
from pandas.core.dtypes.dtypes import BaseMaskedDtype
40+
from pandas.core.dtypes.dtypes import (
41+
ArrowDtype,
42+
BaseMaskedDtype,
43+
)
4144
from pandas.core.dtypes.missing import (
4245
array_equivalent,
4346
is_valid_na_for_dtype,
@@ -767,6 +770,10 @@ def _arith_method(self, other, op):
767770
pd_op = ops.get_array_op(op)
768771
other = ensure_wrapped_if_datetimelike(other)
769772

773+
if isinstance(other, ExtensionArray) and isinstance(other.dtype, ArrowDtype):
774+
# GH#58602
775+
return NotImplemented
776+
770777
if op_name in {"pow", "rpow"} and isinstance(other, np.bool_):
771778
# Avoid DeprecationWarning: In future, it will be an error
772779
# for 'np.bool_' scalars to be interpreted as an index
@@ -843,7 +850,11 @@ def _cmp_method(self, other, op) -> BooleanArray:
843850

844851
mask = None
845852

846-
if isinstance(other, BaseMaskedArray):
853+
if isinstance(other, ExtensionArray) and isinstance(other.dtype, ArrowDtype):
854+
# GH#58602
855+
return NotImplemented
856+
857+
elif isinstance(other, BaseMaskedArray):
847858
other, mask = other._data, other._mask
848859

849860
elif is_list_like(other):

pandas/tests/extension/test_arrow.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3702,6 +3702,28 @@ def test_pow_with_all_na_float():
37023702
tm.assert_series_equal(result, expected)
37033703

37043704

3705+
def test_mul_numpy_nullable_with_pyarrow_float():
3706+
# GH#58602
3707+
left = pd.Series(range(5), dtype="Float64")
3708+
right = pd.Series(range(5), dtype="float64[pyarrow]")
3709+
3710+
expected = pd.Series([0, 1, 4, 9, 16], dtype="float64[pyarrow]")
3711+
3712+
result = left * right
3713+
tm.assert_series_equal(result, expected)
3714+
3715+
result2 = right * left
3716+
tm.assert_series_equal(result2, expected)
3717+
3718+
# while we're here, let's check __eq__
3719+
result3 = left == right
3720+
expected3 = pd.Series([True] * 5, dtype="bool[pyarrow]")
3721+
tm.assert_series_equal(result3, expected3)
3722+
3723+
result4 = right == left
3724+
tm.assert_series_equal(result4, expected3)
3725+
3726+
37053727
@pytest.mark.parametrize(
37063728
"type_name, expected_size",
37073729
[

0 commit comments

Comments
 (0)