@@ -29,6 +29,15 @@ def check_skip(data, op_name):
29
29
pytest .skip ("subtract not implemented for boolean" )
30
30
31
31
32
+ def is_bool_not_implemented (data , op_name ):
33
+ # match non-masked behavior
34
+ return data .dtype .kind == "b" and op_name .strip ("_" ).lstrip ("r" ) in [
35
+ "pow" ,
36
+ "truediv" ,
37
+ "floordiv" ,
38
+ ]
39
+
40
+
32
41
# Test equivalence of scalars, numpy arrays with array ops
33
42
# -----------------------------------------------------------------------------
34
43
@@ -42,9 +51,16 @@ def test_array_scalar_like_equivalence(data, all_arithmetic_operators):
42
51
43
52
# TODO also add len-1 array (np.array([scalar], dtype=data.dtype.numpy_dtype))
44
53
for scalar in [scalar , data .dtype .type (scalar )]:
45
- result = op (data , scalar )
46
- expected = op (data , scalar_array )
47
- tm .assert_extension_array_equal (result , expected )
54
+ if is_bool_not_implemented (data , all_arithmetic_operators ):
55
+ msg = "operator '.*' not implemented for bool dtypes"
56
+ with pytest .raises (NotImplementedError , match = msg ):
57
+ op (data , scalar )
58
+ with pytest .raises (NotImplementedError , match = msg ):
59
+ op (data , scalar_array )
60
+ else :
61
+ result = op (data , scalar )
62
+ expected = op (data , scalar_array )
63
+ tm .assert_extension_array_equal (result , expected )
48
64
49
65
50
66
def test_array_NA (data , all_arithmetic_operators ):
@@ -56,6 +72,15 @@ def test_array_NA(data, all_arithmetic_operators):
56
72
scalar_array = pd .array ([pd .NA ] * len (data ), dtype = data .dtype )
57
73
58
74
mask = data ._mask .copy ()
75
+
76
+ if is_bool_not_implemented (data , all_arithmetic_operators ):
77
+ msg = "operator '.*' not implemented for bool dtypes"
78
+ with pytest .raises (NotImplementedError , match = msg ):
79
+ op (data , scalar )
80
+ # GH#45421 check op doesn't alter data._mask inplace
81
+ tm .assert_numpy_array_equal (mask , data ._mask )
82
+ return
83
+
59
84
result = op (data , scalar )
60
85
# GH#45421 check op doesn't alter data._mask inplace
61
86
tm .assert_numpy_array_equal (mask , data ._mask )
@@ -74,6 +99,14 @@ def test_numpy_array_equivalence(data, all_arithmetic_operators):
74
99
numpy_array = np .array ([scalar ] * len (data ), dtype = data .dtype .numpy_dtype )
75
100
pd_array = pd .array (numpy_array , dtype = data .dtype )
76
101
102
+ if is_bool_not_implemented (data , all_arithmetic_operators ):
103
+ msg = "operator '.*' not implemented for bool dtypes"
104
+ with pytest .raises (NotImplementedError , match = msg ):
105
+ op (data , numpy_array )
106
+ with pytest .raises (NotImplementedError , match = msg ):
107
+ op (data , pd_array )
108
+ return
109
+
77
110
result = op (data , numpy_array )
78
111
expected = op (data , pd_array )
79
112
tm .assert_extension_array_equal (result , expected )
@@ -91,6 +124,14 @@ def test_frame(data, all_arithmetic_operators):
91
124
# DataFrame with scalar
92
125
df = pd .DataFrame ({"A" : data })
93
126
127
+ if is_bool_not_implemented (data , all_arithmetic_operators ):
128
+ msg = "operator '.*' not implemented for bool dtypes"
129
+ with pytest .raises (NotImplementedError , match = msg ):
130
+ op (df , scalar )
131
+ with pytest .raises (NotImplementedError , match = msg ):
132
+ op (data , scalar )
133
+ return
134
+
94
135
result = op (df , scalar )
95
136
expected = pd .DataFrame ({"A" : op (data , scalar )})
96
137
tm .assert_frame_equal (result , expected )
@@ -101,30 +142,25 @@ def test_series(data, all_arithmetic_operators):
101
142
op = tm .get_op_from_name (all_arithmetic_operators )
102
143
check_skip (data , all_arithmetic_operators )
103
144
104
- s = pd .Series (data )
145
+ ser = pd .Series (data )
105
146
106
- # Series with scalar
107
- result = op (s , scalar )
108
- expected = pd .Series (op (data , scalar ))
109
- tm .assert_series_equal (result , expected )
147
+ others = [
148
+ scalar ,
149
+ np .array ([scalar ] * len (data ), dtype = data .dtype .numpy_dtype ),
150
+ pd .array ([scalar ] * len (data ), dtype = data .dtype ),
151
+ pd .Series ([scalar ] * len (data ), dtype = data .dtype ),
152
+ ]
110
153
111
- # Series with np.ndarray
112
- other = np . array ([ scalar ] * len (data ), dtype = data . dtype . numpy_dtype )
113
- result = op ( s , other )
114
- expected = pd . Series ( op ( data , other ))
115
- tm . assert_series_equal ( result , expected )
154
+ for other in others :
155
+ if is_bool_not_implemented (data , all_arithmetic_operators ):
156
+ msg = "operator '.*' not implemented for bool dtypes"
157
+ with pytest . raises ( NotImplementedError , match = msg ):
158
+ op ( ser , other )
116
159
117
- # Series with pd.array
118
- other = pd .array ([scalar ] * len (data ), dtype = data .dtype )
119
- result = op (s , other )
120
- expected = pd .Series (op (data , other ))
121
- tm .assert_series_equal (result , expected )
122
-
123
- # Series with Series
124
- other = pd .Series ([scalar ] * len (data ), dtype = data .dtype )
125
- result = op (s , other )
126
- expected = pd .Series (op (data , other .array ))
127
- tm .assert_series_equal (result , expected )
160
+ else :
161
+ result = op (ser , other )
162
+ expected = pd .Series (op (data , other ))
163
+ tm .assert_series_equal (result , expected )
128
164
129
165
130
166
# Test generic characteristics / errors
@@ -169,6 +205,9 @@ def test_error_len_mismatch(data, all_arithmetic_operators):
169
205
r"numpy boolean subtract, the `\-` operator, is not supported, use "
170
206
r"the bitwise_xor, the `\^` operator, or the logical_xor function instead"
171
207
)
208
+ elif is_bool_not_implemented (data , all_arithmetic_operators ):
209
+ msg = "operator '.*' not implemented for bool dtypes"
210
+ err = NotImplementedError
172
211
173
212
for other in [other , np .array (other )]:
174
213
with pytest .raises (err , match = msg ):
0 commit comments