7
7
from datetime import datetime , timedelta
8
8
import numpy as np
9
9
import pandas as pd
10
- from pandas .compat import u , string_types , PY3
10
+ from pandas .compat import u , string_types , PY3 , DeepChainMap
11
11
from pandas .core .base import StringMixin
12
12
import pandas .core .common as com
13
13
from pandas .computation import expr , ops
14
14
from pandas .computation .ops import is_term
15
+ from pandas .computation .scope import _ensure_scope
15
16
from pandas .computation .expr import BaseExprVisitor
16
17
from pandas .computation .common import _ensure_decoded
17
18
from pandas .tseries .timedeltas import _coerce_scalar_to_timedelta_type
18
19
19
20
20
21
class Scope (expr .Scope ):
21
- __slots__ = 'globals' , 'locals' , 'queryables'
22
-
23
- def __init__ (self , gbls = None , lcls = None , queryables = None , level = 1 ):
24
- super (
25
- Scope ,
26
- self ).__init__ (gbls = gbls ,
27
- lcls = lcls ,
28
- level = level )
22
+ __slots__ = 'queryables' ,
23
+
24
+ def __init__ (self , level , global_dict = None , local_dict = None ,
25
+ queryables = None ):
26
+ super (Scope , self ).__init__ (level + 1 , global_dict = global_dict ,
27
+ local_dict = local_dict )
29
28
self .queryables = queryables or dict ()
30
29
31
30
@@ -48,9 +47,8 @@ def _resolve_name(self):
48
47
raise NameError ('name {0!r} is not defined' .format (self .name ))
49
48
return self .name
50
49
51
- # resolve the rhs (and allow to be None)
52
- return self .env .locals .get (self .name ,
53
- self .env .globals .get (self .name , self .name ))
50
+ # resolve the rhs (and allow it to be None)
51
+ return self .env .resolve (self .name , is_local = False )
54
52
55
53
@property
56
54
def value (self ):
@@ -478,7 +476,7 @@ class Expr(expr.Expr):
478
476
"""
479
477
480
478
def __init__ (self , where , op = None , value = None , queryables = None ,
481
- encoding = None , scope_level = None ):
479
+ encoding = None , scope_level = 0 ):
482
480
483
481
# try to be back compat
484
482
where = self .parse_back_compat (where , op , value )
@@ -488,25 +486,25 @@ def __init__(self, where, op=None, value=None, queryables=None,
488
486
self .filter = None
489
487
self .terms = None
490
488
self ._visitor = None
491
- # capture the environement if needed
492
- lcls = dict ()
493
- if isinstance (where , Expr ):
494
489
495
- lcls .update (where .env .locals )
490
+ # capture the environment if needed
491
+ local_dict = dict ()
492
+
493
+ if isinstance (where , Expr ):
494
+ local_dict .update (where .env .scope )
496
495
where = where .expr
497
496
498
497
elif isinstance (where , (list , tuple )):
499
498
for idx , w in enumerate (where ):
500
499
if isinstance (w , Expr ):
501
- lcls .update (w .env .locals )
500
+ local_dict .update (w .env .scope )
502
501
else :
503
502
w = self .parse_back_compat (w )
504
503
where [idx ] = w
505
504
where = ' & ' .join (["(%s)" % w for w in where ])
506
505
507
506
self .expr = where
508
- self .env = Scope (lcls = lcls )
509
- self .env .update (scope_level )
507
+ self .env = Scope (scope_level + 1 , local_dict = local_dict )
510
508
511
509
if queryables is not None and isinstance (self .expr , string_types ):
512
510
self .env .queryables .update (queryables )
@@ -535,7 +533,7 @@ def parse_back_compat(self, w, op=None, value=None):
535
533
warnings .warn ("passing a tuple into Expr is deprecated, "
536
534
"pass the where as a single string" ,
537
535
DeprecationWarning )
538
-
536
+
539
537
if op is not None :
540
538
if not isinstance (w , string_types ):
541
539
raise TypeError (
0 commit comments