1
-
2
- # flake8: noqa
3
-
4
1
import warnings
5
2
import operator
6
3
from itertools import product
7
- from distutils .version import LooseVersion
8
4
9
5
import pytest
10
6
28
24
29
25
import pandas .computation .expr as expr
30
26
import pandas .util .testing as tm
31
- import pandas ._libs .lib as lib
32
27
from pandas .util .testing import (assert_frame_equal , randbool ,
33
28
assertRaisesRegexp , assert_numpy_array_equal ,
34
29
assert_produces_warning , assert_series_equal ,
35
30
slow )
36
- from pandas .compat import PY3 , u , reduce
31
+ from pandas .compat import PY3 , reduce
37
32
38
33
_series_frame_incompatible = _bool_ops_syms
39
34
_scalar_skip = 'in' , 'not in'
43
38
pytest .mark .skipif (engine == 'numexpr' and not _USE_NUMEXPR ,
44
39
reason = 'numexpr enabled->{enabled}, '
45
40
'installed->{installed}' .format (
46
- enabled = _USE_NUMEXPR ,
47
- installed = _NUMEXPR_INSTALLED ))(engine )
48
- for engine in _engines
41
+ enabled = _USE_NUMEXPR ,
42
+ installed = _NUMEXPR_INSTALLED ))(engine )
43
+ for engine in _engines # noqa
49
44
))
50
45
def engine (request ):
51
46
return request .param
@@ -66,22 +61,23 @@ def _eval_single_bin(lhs, cmp1, rhs, engine):
66
61
try :
67
62
return c (lhs , rhs )
68
63
except ValueError as e :
69
- if str (e ).startswith ('negative number cannot be raised to a fractional power' ):
64
+ if str (e ).startswith ('negative number cannot be '
65
+ 'raised to a fractional power' ):
70
66
return np .nan
71
67
raise
72
68
return c (lhs , rhs )
73
69
74
70
75
71
def _series_and_2d_ndarray (lhs , rhs ):
76
72
return ((isinstance (lhs , Series ) and
77
- isinstance (rhs , np .ndarray ) and rhs .ndim > 1 )
78
- or (isinstance (rhs , Series ) and
79
- isinstance (lhs , np .ndarray ) and lhs .ndim > 1 ))
73
+ isinstance (rhs , np .ndarray ) and rhs .ndim > 1 ) or
74
+ (isinstance (rhs , Series ) and
75
+ isinstance (lhs , np .ndarray ) and lhs .ndim > 1 ))
80
76
81
77
82
78
def _series_and_frame (lhs , rhs ):
83
- return ((isinstance (lhs , Series ) and isinstance (rhs , DataFrame ))
84
- or (isinstance (rhs , Series ) and isinstance (lhs , DataFrame )))
79
+ return ((isinstance (lhs , Series ) and isinstance (rhs , DataFrame )) or
80
+ (isinstance (rhs , Series ) and isinstance (lhs , DataFrame )))
85
81
86
82
87
83
def _bool_and_frame (lhs , rhs ):
@@ -228,27 +224,29 @@ def check_complex_cmp_op(self, lhs, cmp1, rhs, binop, cmp2):
228
224
else :
229
225
lhs_new = _eval_single_bin (lhs , cmp1 , rhs , self .engine )
230
226
rhs_new = _eval_single_bin (lhs , cmp2 , rhs , self .engine )
231
- if (isinstance (lhs_new , Series ) and isinstance (rhs_new , DataFrame )
232
- and binop in _series_frame_incompatible ):
227
+ if (isinstance (lhs_new , Series ) and
228
+ isinstance (rhs_new , DataFrame ) and
229
+ binop in _series_frame_incompatible ):
233
230
pass
234
231
# TODO: the code below should be added back when left and right
235
232
# hand side bool ops are fixed.
236
-
233
+ #
237
234
# try:
238
- # self.assertRaises(Exception, pd.eval, ex,
239
- #local_dict={'lhs': lhs, 'rhs': rhs},
240
- # engine=self.engine, parser=self.parser)
235
+ # self.assertRaises(Exception, pd.eval, ex,
236
+ # local_dict={'lhs': lhs, 'rhs': rhs},
237
+ # engine=self.engine, parser=self.parser)
241
238
# except AssertionError:
242
- #import ipdb; ipdb.set_trace()
243
- # raise
239
+ # import ipdb
240
+ #
241
+ # ipdb.set_trace()
242
+ # raise
244
243
else :
245
244
expected = _eval_single_bin (
246
245
lhs_new , binop , rhs_new , self .engine )
247
246
result = pd .eval (ex , engine = self .engine , parser = self .parser )
248
247
self .check_equal (result , expected )
249
248
250
249
def check_chained_cmp_op (self , lhs , cmp1 , mid , cmp2 , rhs ):
251
- skip_these = _scalar_skip
252
250
253
251
def check_operands (left , right , cmp_op ):
254
252
return _eval_single_bin (left , cmp_op , right , self .engine )
@@ -334,7 +332,8 @@ def get_expected_pow_result(self, lhs, rhs):
334
332
try :
335
333
expected = _eval_single_bin (lhs , '**' , rhs , self .engine )
336
334
except ValueError as e :
337
- if str (e ).startswith ('negative number cannot be raised to a fractional power' ):
335
+ if str (e ).startswith ('negative number cannot be '
336
+ 'raised to a fractional power' ):
338
337
if self .engine == 'python' :
339
338
pytest .skip (str (e ))
340
339
else :
@@ -650,7 +649,7 @@ def test_disallow_scalar_bool_ops(self):
650
649
exprs += '2 * x > 2 or 1 and 2' ,
651
650
exprs += '2 * df > 3 and 1 or a' ,
652
651
653
- x , a , b , df = np .random .randn (3 ), 1 , 2 , DataFrame (randn (3 , 2 ))
652
+ x , a , b , df = np .random .randn (3 ), 1 , 2 , DataFrame (randn (3 , 2 )) # noqa
654
653
for ex in exprs :
655
654
with tm .assertRaises (NotImplementedError ):
656
655
pd .eval (ex , engine = self .engine , parser = self .parser )
@@ -682,7 +681,7 @@ def test_identical(self):
682
681
tm .assert_numpy_array_equal (result , np .array ([1.5 ]))
683
682
self .assertEqual (result .shape , (1 , ))
684
683
685
- x = np .array ([False ])
684
+ x = np .array ([False ]) # noqa
686
685
result = pd .eval ('x' , engine = self .engine , parser = self .parser )
687
686
tm .assert_numpy_array_equal (result , np .array ([False ]))
688
687
self .assertEqual (result .shape , (1 , ))
@@ -792,9 +791,8 @@ def check_chained_cmp_op(self, lhs, cmp1, mid, cmp2, rhs):
792
791
f = lambda * args , ** kwargs : np .random .randn ()
793
792
794
793
795
- #-------------------------------------
796
- # typecasting rules consistency with python
797
- # issue #12388
794
+ # -------------------------------------
795
+ # gh-12388: Typecasting rules consistency with python
798
796
799
797
800
798
class TestTypeCasting (object ):
@@ -817,8 +815,8 @@ def test_binop_typecasting(self, engine, parser, op, dt):
817
815
assert_frame_equal (res , eval (s ))
818
816
819
817
820
- #-------------------------------------
821
- # basic and complex alignment
818
+ # -------------------------------------
819
+ # Basic and complex alignment
822
820
823
821
def _is_datetime (x ):
824
822
return issubclass (x .dtype .type , np .datetime64 )
@@ -1064,8 +1062,8 @@ def test_performance_warning_for_poor_alignment(self, engine, parser):
1064
1062
tm .assert_equal (msg , expected )
1065
1063
1066
1064
1067
- #------------------------------------
1068
- # slightly more complex ops
1065
+ # ------------------------------------
1066
+ # Slightly more complex ops
1069
1067
1070
1068
class TestOperationsNumExprPandas (tm .TestCase ):
1071
1069
@@ -1156,7 +1154,7 @@ def test_single_variable(self):
1156
1154
def test_truediv (self ):
1157
1155
s = np .array ([1 ])
1158
1156
ex = 's / 1'
1159
- d = {'s' : s }
1157
+ d = {'s' : s } # noqa
1160
1158
1161
1159
if PY3 :
1162
1160
res = self .eval (ex , truediv = False )
@@ -1204,7 +1202,7 @@ def test_truediv(self):
1204
1202
self .assertEqual (res , expec )
1205
1203
1206
1204
def test_failing_subscript_with_name_error (self ):
1207
- df = DataFrame (np .random .randn (5 , 3 ))
1205
+ df = DataFrame (np .random .randn (5 , 3 )) # noqa
1208
1206
with tm .assertRaises (NameError ):
1209
1207
self .eval ('df[x > 2] > 2' )
1210
1208
@@ -1501,7 +1499,7 @@ def setUpClass(cls):
1501
1499
cls .arith_ops )
1502
1500
1503
1501
def test_check_many_exprs (self ):
1504
- a = 1
1502
+ a = 1 # noqa
1505
1503
expr = ' * ' .join ('a' * 33 )
1506
1504
expected = 1
1507
1505
res = pd .eval (expr , engine = self .engine , parser = self .parser )
@@ -1526,13 +1524,13 @@ def test_fails_not(self):
1526
1524
engine = self .engine )
1527
1525
1528
1526
def test_fails_ampersand (self ):
1529
- df = DataFrame (np .random .randn (5 , 3 ))
1527
+ df = DataFrame (np .random .randn (5 , 3 )) # noqa
1530
1528
ex = '(df + 2)[df > 1] > 0 & (df > 0)'
1531
1529
with tm .assertRaises (NotImplementedError ):
1532
1530
pd .eval (ex , parser = self .parser , engine = self .engine )
1533
1531
1534
1532
def test_fails_pipe (self ):
1535
- df = DataFrame (np .random .randn (5 , 3 ))
1533
+ df = DataFrame (np .random .randn (5 , 3 )) # noqa
1536
1534
ex = '(df + 2)[df > 1] > 0 | (df > 0)'
1537
1535
with tm .assertRaises (NotImplementedError ):
1538
1536
pd .eval (ex , parser = self .parser , engine = self .engine )
@@ -1728,15 +1726,15 @@ def test_global_scope(self, engine, parser):
1728
1726
parser = parser ))
1729
1727
1730
1728
def test_no_new_locals (self , engine , parser ):
1731
- x = 1
1729
+ x = 1 # noqa
1732
1730
lcls = locals ().copy ()
1733
1731
pd .eval ('x + 1' , local_dict = lcls , engine = engine , parser = parser )
1734
1732
lcls2 = locals ().copy ()
1735
1733
lcls2 .pop ('lcls' )
1736
1734
tm .assert_equal (lcls , lcls2 )
1737
1735
1738
1736
def test_no_new_globals (self , engine , parser ):
1739
- x = 1
1737
+ x = 1 # noqa
1740
1738
gbls = globals ().copy ()
1741
1739
pd .eval ('x + 1' , engine = engine , parser = parser )
1742
1740
gbls2 = globals ().copy ()
@@ -1787,15 +1785,16 @@ def test_name_error_exprs(engine, parser):
1787
1785
1788
1786
1789
1787
def test_invalid_local_variable_reference (engine , parser ):
1790
- a , b = 1 , 2
1788
+ a , b = 1 , 2 # noqa
1791
1789
exprs = 'a + @b' , '@a + b' , '@a + @b'
1792
- for expr in exprs :
1790
+
1791
+ for _expr in exprs :
1793
1792
if parser != 'pandas' :
1794
1793
with tm .assertRaisesRegexp (SyntaxError , "The '@' prefix is only" ):
1795
- pd .eval (exprs , engine = engine , parser = parser )
1794
+ pd .eval (_expr , engine = engine , parser = parser )
1796
1795
else :
1797
1796
with tm .assertRaisesRegexp (SyntaxError , "The '@' prefix is not" ):
1798
- pd .eval (exprs , engine = engine , parser = parser )
1797
+ pd .eval (_expr , engine = engine , parser = parser )
1799
1798
1800
1799
1801
1800
def test_numexpr_builtin_raises (engine , parser ):
@@ -1834,9 +1833,9 @@ def test_more_than_one_expression_raises(engine, parser):
1834
1833
def test_bool_ops_fails_on_scalars (lhs , cmp , rhs , engine , parser ):
1835
1834
gen = {int : lambda : np .random .randint (10 ), float : np .random .randn }
1836
1835
1837
- mid = gen [lhs ]()
1838
- lhs = gen [lhs ]()
1839
- rhs = gen [rhs ]()
1836
+ mid = gen [lhs ]() # noqa
1837
+ lhs = gen [lhs ]() # noqa
1838
+ rhs = gen [rhs ]() # noqa
1840
1839
1841
1840
ex1 = 'lhs {0} mid {1} rhs' .format (cmp , cmp )
1842
1841
ex2 = 'lhs {0} mid and mid {1} rhs' .format (cmp , cmp )
0 commit comments