@@ -29,6 +29,15 @@ def check_skip(data, op_name):
2929 pytest .skip ("subtract not implemented for boolean" )
3030
3131
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+
3241# Test equivalence of scalars, numpy arrays with array ops
3342# -----------------------------------------------------------------------------
3443
@@ -42,9 +51,16 @@ def test_array_scalar_like_equivalence(data, all_arithmetic_operators):
4251
4352 # TODO also add len-1 array (np.array([scalar], dtype=data.dtype.numpy_dtype))
4453 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 )
4864
4965
5066def test_array_NA (data , all_arithmetic_operators ):
@@ -56,6 +72,15 @@ def test_array_NA(data, all_arithmetic_operators):
5672 scalar_array = pd .array ([pd .NA ] * len (data ), dtype = data .dtype )
5773
5874 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+
5984 result = op (data , scalar )
6085 # GH#45421 check op doesn't alter data._mask inplace
6186 tm .assert_numpy_array_equal (mask , data ._mask )
@@ -74,6 +99,14 @@ def test_numpy_array_equivalence(data, all_arithmetic_operators):
7499 numpy_array = np .array ([scalar ] * len (data ), dtype = data .dtype .numpy_dtype )
75100 pd_array = pd .array (numpy_array , dtype = data .dtype )
76101
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+
77110 result = op (data , numpy_array )
78111 expected = op (data , pd_array )
79112 tm .assert_extension_array_equal (result , expected )
@@ -91,6 +124,14 @@ def test_frame(data, all_arithmetic_operators):
91124 # DataFrame with scalar
92125 df = pd .DataFrame ({"A" : data })
93126
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+
94135 result = op (df , scalar )
95136 expected = pd .DataFrame ({"A" : op (data , scalar )})
96137 tm .assert_frame_equal (result , expected )
@@ -101,30 +142,25 @@ def test_series(data, all_arithmetic_operators):
101142 op = tm .get_op_from_name (all_arithmetic_operators )
102143 check_skip (data , all_arithmetic_operators )
103144
104- s = pd .Series (data )
145+ ser = pd .Series (data )
105146
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+ ]
110153
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 )
116159
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 )
128164
129165
130166# Test generic characteristics / errors
@@ -169,6 +205,9 @@ def test_error_len_mismatch(data, all_arithmetic_operators):
169205 r"numpy boolean subtract, the `\-` operator, is not supported, use "
170206 r"the bitwise_xor, the `\^` operator, or the logical_xor function instead"
171207 )
208+ elif is_bool_not_implemented (data , all_arithmetic_operators ):
209+ msg = "operator '.*' not implemented for bool dtypes"
210+ err = NotImplementedError
172211
173212 for other in [other , np .array (other )]:
174213 with pytest .raises (err , match = msg ):
0 commit comments