Skip to content

Commit f245a45

Browse files
committed
Carve-out for array-castable attributes
1 parent c9d4896 commit f245a45

File tree

10 files changed

+45
-14
lines changed

10 files changed

+45
-14
lines changed

pandas/core/arrays/arrow/array.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -943,8 +943,10 @@ def _op_method_error_message(self, other, op) -> str:
943943
)
944944

945945
def _evaluate_op_method(self, other, op, arrow_funcs) -> Self:
946-
if is_list_like(other) and not isinstance(
947-
other, (np.ndarray, ExtensionArray, list)
946+
if (
947+
is_list_like(other)
948+
and not isinstance(other, (np.ndarray, ExtensionArray, list))
949+
and not ops.has_castable_attr(other)
948950
):
949951
warnings.warn(
950952
f"Operation with {type(other).__name__} are deprecated. "

pandas/core/arrays/boolean.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,9 @@ def _logical_method(self, other, op):
382382
if isinstance(other, BooleanArray):
383383
other, mask = other._data, other._mask
384384
elif is_list_like(other):
385-
if not isinstance(other, (list, ExtensionArray, np.ndarray)):
385+
if not isinstance(
386+
other, (list, ExtensionArray, np.ndarray)
387+
) and not ops.has_castable_attr(other):
386388
warnings.warn(
387389
f"Operation with {type(other).__name__} are deprecated. "
388390
"In a future version these will be treated as scalar-like. "

pandas/core/arrays/datetimelike.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -970,7 +970,9 @@ def _cmp_method(self, other, op):
970970
return op(self.ravel(), other.ravel()).reshape(self.shape)
971971

972972
if is_list_like(other):
973-
if not isinstance(other, (list, np.ndarray, ExtensionArray)):
973+
if not isinstance(
974+
other, (list, np.ndarray, ExtensionArray)
975+
) and not ops.has_castable_attr(other):
974976
warnings.warn(
975977
f"Operation with {type(other).__name__} are deprecated. "
976978
"In a future version these will be treated as scalar-like. "

pandas/core/arrays/interval.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
notna,
7676
)
7777

78+
from pandas.core import ops
7879
from pandas.core.algorithms import (
7980
isin,
8081
take,
@@ -845,7 +846,9 @@ def __setitem__(self, key, value) -> None:
845846
def _cmp_method(self, other, op):
846847
# ensure pandas array for list-like and eliminate non-interval scalars
847848
if is_list_like(other):
848-
if not isinstance(other, (list, np.ndarray, ExtensionArray)):
849+
if not isinstance(
850+
other, (list, np.ndarray, ExtensionArray)
851+
) and not ops.has_castable_attr(other):
849852
warnings.warn(
850853
f"Operation with {type(other).__name__} are deprecated. "
851854
"In a future version these will be treated as scalar-like. "

pandas/core/arrays/masked.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -747,8 +747,10 @@ def _arith_method(self, other, op):
747747
op_name = op.__name__
748748
omask = None
749749

750-
if is_list_like(other) and not isinstance(
751-
other, (list, np.ndarray, ExtensionArray)
750+
if (
751+
is_list_like(other)
752+
and not isinstance(other, (list, np.ndarray, ExtensionArray))
753+
and not ops.has_castable_attr(other)
752754
):
753755
warnings.warn(
754756
f"Operation with {type(other).__name__} are deprecated. "
@@ -863,7 +865,9 @@ def _cmp_method(self, other, op) -> BooleanArray:
863865
other, mask = other._data, other._mask
864866

865867
elif is_list_like(other):
866-
if not isinstance(other, (list, np.ndarray, ExtensionArray)):
868+
if not isinstance(
869+
other, (list, np.ndarray, ExtensionArray)
870+
) and not ops.has_castable_attr(other):
867871
warnings.warn(
868872
f"Operation with {type(other).__name__} are deprecated. "
869873
"In a future version these will be treated as scalar-like. "

pandas/core/arrays/sparse/array.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,10 @@
6969
notna,
7070
)
7171

72-
from pandas.core import arraylike
72+
from pandas.core import (
73+
arraylike,
74+
ops,
75+
)
7376
import pandas.core.algorithms as algos
7477
from pandas.core.arraylike import OpsMixin
7578
from pandas.core.arrays import ExtensionArray
@@ -1808,7 +1811,9 @@ def _arith_method(self, other, op):
18081811
return _wrap_result(op_name, result, self.sp_index, fill)
18091812

18101813
else:
1811-
if not isinstance(other, (list, np.ndarray, ExtensionArray)):
1814+
if not isinstance(
1815+
other, (list, np.ndarray, ExtensionArray)
1816+
) and not ops.has_castable_attr(other):
18121817
warnings.warn(
18131818
f"Operation with {type(other).__name__} are deprecated. "
18141819
"In a future version these will be treated as scalar-like. "
@@ -1830,8 +1835,10 @@ def _arith_method(self, other, op):
18301835
return _sparse_array_op(self, other, op, op_name)
18311836

18321837
def _cmp_method(self, other, op) -> SparseArray:
1833-
if is_list_like(other) and not isinstance(
1834-
other, (list, np.ndarray, ExtensionArray)
1838+
if (
1839+
is_list_like(other)
1840+
and not isinstance(other, (list, np.ndarray, ExtensionArray))
1841+
and not ops.has_castable_attr(other)
18351842
):
18361843
warnings.warn(
18371844
f"Operation with {type(other).__name__} are deprecated. "

pandas/core/arrays/string_.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1102,7 +1102,9 @@ def _cmp_method(self, other, op):
11021102
valid = ~mask
11031103

11041104
if lib.is_list_like(other):
1105-
if not isinstance(other, (list, ExtensionArray, np.ndarray)):
1105+
if not isinstance(
1106+
other, (list, ExtensionArray, np.ndarray)
1107+
) and not ops.has_castable_attr(other):
11061108
warnings.warn(
11071109
f"Operation with {type(other).__name__} are deprecated. "
11081110
"In a future version these will be treated as scalar-like. "

pandas/core/frame.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8485,7 +8485,9 @@ def to_series(right):
84858485
)
84868486

84878487
elif is_list_like(right) and not isinstance(right, (Series, DataFrame)):
8488-
if not isinstance(right, (np.ndarray, ExtensionArray, Index, list, dict)):
8488+
if not isinstance(
8489+
right, (np.ndarray, ExtensionArray, Index, list, dict)
8490+
) and not ops.has_castable_attr(right):
84898491
warnings.warn(
84908492
f"Operation with {type(right).__name__} are deprecated. "
84918493
"In a future version these will be treated as scalar-like. "

pandas/core/ops/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
)
1818
from pandas.core.ops.common import (
1919
get_op_result_name,
20+
has_castable_attr,
2021
unpack_zerodim_and_defer,
2122
)
2223
from pandas.core.ops.docstrings import make_flex_doc
@@ -71,6 +72,7 @@
7172
"fill_binop",
7273
"get_array_op",
7374
"get_op_result_name",
75+
"has_castable_attr",
7476
"invalid_comparison",
7577
"kleene_and",
7678
"kleene_or",

pandas/core/ops/common.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@
2121
from pandas._typing import F
2222

2323

24+
def has_castable_attr(obj) -> bool:
25+
attrs = ["__array__", "__dlpack__", "__arrow_c_array__", "__arrow_c_stream__"]
26+
return any(hasattr(obj, name) for name in attrs)
27+
28+
2429
def unpack_zerodim_and_defer(name: str) -> Callable[[F], F]:
2530
"""
2631
Boilerplate for pandas conventions in arithmetic and comparison methods.

0 commit comments

Comments
 (0)