diff --git a/pandas/tests/computation/test_eval.py b/pandas/tests/computation/test_eval.py index 062d1876141f8..e52db86c7fd5e 100644 --- a/pandas/tests/computation/test_eval.py +++ b/pandas/tests/computation/test_eval.py @@ -23,16 +23,13 @@ from pandas.core.computation.expressions import ( _NUMEXPR_INSTALLED, _USE_NUMEXPR) from pandas.core.computation.ops import ( - _arith_ops_syms, _binary_math_ops, _binary_ops_dict, _bool_ops_syms, + _arith_ops_syms, _binary_math_ops, _binary_ops_dict, _special_case_arith_ops_syms, _unary_math_ops) import pandas.util.testing as tm from pandas.util.testing import ( assert_frame_equal, assert_numpy_array_equal, assert_produces_warning, assert_series_equal, makeCustomDataframe as mkdf, randbool) -_series_frame_incompatible = _bool_ops_syms -_scalar_skip = 'in', 'not in' - @pytest.fixture(params=( pytest.param(engine, @@ -162,13 +159,21 @@ def teardown_method(self, method): del self.pandas_rhses, self.pandas_lhses, self.current_engines @pytest.mark.slow - def test_complex_cmp_ops(self): - cmp_ops = ('!=', '==', '<=', '>=', '<', '>') - cmp2_ops = ('>', '<') - for lhs, cmp1, rhs, binop, cmp2 in product(self.lhses, cmp_ops, - self.rhses, self.bin_ops, - cmp2_ops): - self.check_complex_cmp_op(lhs, cmp1, rhs, binop, cmp2) + @pytest.mark.parametrize('cmp1', ['!=', '==', '<=', '>=', '<', '>'], + ids=['ne', 'eq', 'le', 'ge', 'lt', 'gt']) + @pytest.mark.parametrize('cmp2', ['>', '<'], ids=['gt', 'lt']) + def test_complex_cmp_ops(self, cmp1, cmp2): + for lhs, rhs, binop in product( + self.lhses, self.rhses, self.bin_ops): + lhs_new = _eval_single_bin(lhs, cmp1, rhs, self.engine) + rhs_new = _eval_single_bin(lhs, cmp2, rhs, self.engine) + expected = _eval_single_bin( + lhs_new, binop, rhs_new, self.engine) + + ex = '(lhs {cmp1} rhs) {binop} (lhs {cmp2} rhs)'.format( + cmp1=cmp1, binop=binop, cmp2=cmp2) + result = pd.eval(ex, engine=self.engine, parser=self.parser) + self.check_equal(result, expected) def test_simple_cmp_ops(self): bool_lhses = (DataFrame(randbool(size=(10, 5))), @@ -225,41 +230,6 @@ def check_equal(self, result, expected): else: assert result == expected - def check_complex_cmp_op(self, lhs, cmp1, rhs, binop, cmp2): - skip_these = _scalar_skip - ex = '(lhs {cmp1} rhs) {binop} (lhs {cmp2} rhs)'.format(cmp1=cmp1, - binop=binop, - cmp2=cmp2) - scalar_with_in_notin = (is_scalar(rhs) and (cmp1 in skip_these or - cmp2 in skip_these)) - if scalar_with_in_notin: - with pytest.raises(TypeError): - pd.eval(ex, engine=self.engine, parser=self.parser) - with pytest.raises(TypeError): - pd.eval(ex, engine=self.engine, parser=self.parser, - local_dict={'lhs': lhs, 'rhs': rhs}) - else: - lhs_new = _eval_single_bin(lhs, cmp1, rhs, self.engine) - rhs_new = _eval_single_bin(lhs, cmp2, rhs, self.engine) - if (isinstance(lhs_new, Series) and - isinstance(rhs_new, DataFrame) and - binop in _series_frame_incompatible): - pass - # TODO: the code below should be added back when left and right - # hand side bool ops are fixed. - # - # try: - # pytest.raises(Exception, pd.eval, ex, - # local_dict={'lhs': lhs, 'rhs': rhs}, - # engine=self.engine, parser=self.parser) - # except AssertionError: - # raise - else: - expected = _eval_single_bin( - lhs_new, binop, rhs_new, self.engine) - result = pd.eval(ex, engine=self.engine, parser=self.parser) - self.check_equal(result, expected) - def check_chained_cmp_op(self, lhs, cmp1, mid, cmp2, rhs): def check_operands(left, right, cmp_op):