Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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/v3.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -998,6 +998,7 @@ Numeric
- Bug in :meth:`Series.dot` returning ``object`` dtype for :class:`ArrowDtype` and nullable-dtype data (:issue:`61375`)
- Bug in :meth:`Series.std` and :meth:`Series.var` when using complex-valued data (:issue:`61645`)
- Bug in ``np.matmul`` with :class:`Index` inputs raising a ``TypeError`` (:issue:`57079`)
- Bug in arithmetic operations between objects with numpy-nullable dtype and :class:`ArrowDtype` incorrectly raising (:issue:`58602`)

Conversion
^^^^^^^^^^
Expand Down
15 changes: 13 additions & 2 deletions pandas/core/arrays/masked.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@
is_string_dtype,
pandas_dtype,
)
from pandas.core.dtypes.dtypes import BaseMaskedDtype
from pandas.core.dtypes.dtypes import (
ArrowDtype,
BaseMaskedDtype,
)
from pandas.core.dtypes.missing import (
array_equivalent,
is_valid_na_for_dtype,
Expand Down Expand Up @@ -767,6 +770,10 @@ def _arith_method(self, other, op):
pd_op = ops.get_array_op(op)
other = ensure_wrapped_if_datetimelike(other)

if isinstance(other, ExtensionArray) and isinstance(other.dtype, ArrowDtype):
# GH#58602
return NotImplemented

if op_name in {"pow", "rpow"} and isinstance(other, np.bool_):
# Avoid DeprecationWarning: In future, it will be an error
# for 'np.bool_' scalars to be interpreted as an index
Expand Down Expand Up @@ -843,7 +850,11 @@ def _cmp_method(self, other, op) -> BooleanArray:

mask = None

if isinstance(other, BaseMaskedArray):
if isinstance(other, ExtensionArray) and isinstance(other.dtype, ArrowDtype):
# GH#58602
return NotImplemented

elif isinstance(other, BaseMaskedArray):
other, mask = other._data, other._mask

elif is_list_like(other):
Expand Down
22 changes: 22 additions & 0 deletions pandas/tests/extension/test_arrow.py
Original file line number Diff line number Diff line change
Expand Up @@ -3700,3 +3700,25 @@ def test_pow_with_all_na_float():
result = s.pow(2)
expected = pd.Series([pd.NA, pd.NA], dtype="float64[pyarrow]")
tm.assert_series_equal(result, expected)


def test_mul_numpy_nullable_with_pyarrow_float():
# GH#58602
left = pd.Series(range(5), dtype="Float64")
right = pd.Series(range(5), dtype="float64[pyarrow]")

expected = pd.Series([0, 1, 4, 9, 16], dtype="float64[pyarrow]")

result = left * right
tm.assert_series_equal(result, expected)

result2 = right * left
tm.assert_series_equal(result2, expected)

# while we're here, let's check __eq__
result3 = left == right
expected3 = pd.Series([True] * 5, dtype="bool[pyarrow]")
tm.assert_series_equal(result3, expected3)

result4 = right == left
tm.assert_series_equal(result4, expected3)
Loading