13
13
14
14
from pandas .core .dtypes .common import (
15
15
is_bool ,
16
+ is_float ,
16
17
is_list_like ,
17
18
is_scalar ,
18
19
)
@@ -121,7 +122,10 @@ def _is_py3_complex_incompat(result, expected):
121
122
122
123
123
124
# TODO: using range(5) here is a kludge
124
- @pytest .fixture (params = list (range (5 )))
125
+ @pytest .fixture (
126
+ params = list (range (5 )),
127
+ ids = ["DataFrame" , "Series" , "SeriesNaN" , "DataFrameNaN" , "float" ],
128
+ )
125
129
def lhs (request ):
126
130
127
131
nan_df1 = DataFrame (np .random .rand (10 , 5 ))
@@ -168,7 +172,12 @@ def current_engines(self):
168
172
@pytest .mark .parametrize ("binop" , expr .BOOL_OPS_SYMS )
169
173
def test_complex_cmp_ops (self , cmp1 , cmp2 , binop , lhs , rhs ):
170
174
if binop in self .exclude_bool :
171
- pytest .skip ()
175
+ # i.e. "&" and "|"
176
+ msg = "'BoolOp' nodes are not implemented"
177
+ with pytest .raises (NotImplementedError , match = msg ):
178
+ ex = f"(lhs { cmp1 } rhs) { binop } (lhs { cmp2 } rhs)"
179
+ result = pd .eval (ex , engine = self .engine , parser = self .parser )
180
+ return
172
181
173
182
lhs_new = _eval_single_bin (lhs , cmp1 , rhs , self .engine )
174
183
rhs_new = _eval_single_bin (lhs , cmp2 , rhs , self .engine )
@@ -180,9 +189,6 @@ def test_complex_cmp_ops(self, cmp1, cmp2, binop, lhs, rhs):
180
189
181
190
@pytest .mark .parametrize ("cmp_op" , expr .CMP_OPS_SYMS )
182
191
def test_simple_cmp_ops (self , cmp_op ):
183
- if cmp_op in self .exclude_cmp :
184
- pytest .skip ()
185
-
186
192
bool_lhses = (
187
193
DataFrame (tm .randbool (size = (10 , 5 ))),
188
194
Series (tm .randbool ((5 ,))),
@@ -193,6 +199,15 @@ def test_simple_cmp_ops(self, cmp_op):
193
199
Series (tm .randbool ((5 ,))),
194
200
tm .randbool (),
195
201
)
202
+
203
+ if cmp_op in self .exclude_cmp :
204
+ msg = "'(In|NotIn)' nodes are not implemented"
205
+ for lhs , rhs in product (bool_lhses , bool_rhses ):
206
+
207
+ with pytest .raises (NotImplementedError , match = msg ):
208
+ self .check_simple_cmp_op (lhs , cmp_op , rhs )
209
+ return
210
+
196
211
for lhs , rhs in product (bool_lhses , bool_rhses ):
197
212
self .check_simple_cmp_op (lhs , cmp_op , rhs )
198
213
@@ -213,15 +228,29 @@ def test_pow(self, lhs, rhs):
213
228
214
229
@pytest .mark .parametrize ("op" , expr .CMP_OPS_SYMS )
215
230
def test_single_invert_op (self , op , lhs ):
216
- if op in self .exclude_cmp :
217
- pytest .skip ()
218
-
219
231
self .check_single_invert_op (lhs , op )
220
232
221
233
@pytest .mark .parametrize ("op" , expr .CMP_OPS_SYMS )
222
- def test_compound_invert_op (self , op , lhs , rhs ):
234
+ def test_compound_invert_op (self , op , lhs , rhs , request ):
223
235
if op in self .exclude_cmp :
224
- pytest .skip ()
236
+
237
+ msg = "'(In|NotIn)' nodes are not implemented"
238
+ with pytest .raises (NotImplementedError , match = msg ):
239
+ self .check_compound_invert_op (lhs , op , rhs )
240
+ return
241
+
242
+ if (
243
+ is_float (lhs )
244
+ and not is_float (rhs )
245
+ and op in ["in" , "not in" ]
246
+ and self .engine == "python"
247
+ and self .parser == "pandas"
248
+ ):
249
+ mark = pytest .mark .xfail (
250
+ reason = "Looks like expected is negative, unclear whether "
251
+ "expected is incorrect or result is incorrect"
252
+ )
253
+ request .node .add_marker (mark )
225
254
226
255
self .check_compound_invert_op (lhs , op , rhs )
227
256
@@ -753,8 +782,8 @@ def test_disallow_python_keywords(self):
753
782
754
783
@td .skip_if_no_ne
755
784
class TestEvalNumexprPython (TestEvalNumexprPandas ):
756
- exclude_cmp = ["in" , "not in" ]
757
- exclude_bool = ["and" , "or" ]
785
+ exclude_cmp : list [ str ] = ["in" , "not in" ]
786
+ exclude_bool : list [ str ] = ["and" , "or" ]
758
787
759
788
engine = "numexpr"
760
789
parser = "python"
@@ -802,6 +831,8 @@ def check_alignment(self, result, nlhs, ghs, op):
802
831
class TestEvalPythonPandas (TestEvalPythonPython ):
803
832
engine = "python"
804
833
parser = "pandas"
834
+ exclude_bool : list [str ] = []
835
+ exclude_cmp : list [str ] = []
805
836
806
837
def check_chained_cmp_op (self , lhs , cmp1 , mid , cmp2 , rhs ):
807
838
TestEvalNumexprPandas .check_chained_cmp_op (self , lhs , cmp1 , mid , cmp2 , rhs )
0 commit comments