@@ -635,20 +635,16 @@ def genhash(self, code, package_level=-1):
635635 def get_empty_scope (self , inner = False ):
636636 """Get an empty scope for the parsing_context."""
637637 parent = self .current_parsing_context ("scope" )
638+ if parent is not None and parent ["all_vars" ] is None :
639+ inner = True
638640 return {
639641 "final_vars" : {},
640642 "pure_vars" : {},
641643 "all_vars" : None if inner else set (),
642644 "parent" : parent ,
645+ "callbacks" : [],
643646 }
644647
645- def init_parsing_context (self , inner = False ):
646- """Initialize parsing context."""
647- self .parsing_context = defaultdict (list )
648- # initialize module-level scopes
649- self .parsing_context ["scope" ].append (self .get_empty_scope (inner = inner ))
650- return self .parsing_context
651-
652648 def reset (self , keep_state = False , filename = None ):
653649 """Reset references.
654650
@@ -683,8 +679,7 @@ def reset(self, keep_state=False, filename=None):
683679 self .shown_warnings = set ()
684680 if not keep_state :
685681 self .computation_graph_caches = defaultdict (staledict )
686- self .final_checks = []
687- self .init_parsing_context ()
682+ self .parsing_context = defaultdict (list )
688683
689684 @contextmanager
690685 def inner_environment (self , ln = None ):
@@ -702,11 +697,13 @@ def inner_environment(self, ln=None):
702697 num_lines , self .num_lines = self .num_lines , 0
703698 remaining_original , self .remaining_original = self .remaining_original , None
704699 shown_warnings , self .shown_warnings = self .shown_warnings , set ()
705- parsing_context = self .parsing_context
706- self .init_parsing_context (inner = True )
700+ parsing_context , self .parsing_context = self .parsing_context , defaultdict (list )
707701 try :
708- with ComputationNode .using_overrides ():
709- yield
702+ with self .add_to_parsing_context ({
703+ "scope" : self .get_empty_scope (inner = True ),
704+ }):
705+ with ComputationNode .using_overrides ():
706+ yield
710707 finally :
711708 self .outer_ln = outer_ln
712709 self .line_numbers = line_numbers
@@ -1525,8 +1522,8 @@ def parsing(self, keep_state=False, codepath=None):
15251522 """Acquire the lock and reset the parser."""
15261523 filename = None if codepath is None else os .path .basename (codepath )
15271524 with self .lock :
1528- self .reset (keep_state , filename )
15291525 Compiler .current_compiler = self
1526+ self .reset (keep_state , filename )
15301527 yield
15311528
15321529 def streamline (self , grammars , inputstring = None , force = False , inner = False ):
@@ -1557,8 +1554,6 @@ def run_final_checks(self, original, keep_state=False):
15571554 if info ["imported" ] and not info ["referenced" ]:
15581555 for loc in info ["imported" ]:
15591556 self .strict_err_or_warn ("found unused import " + repr (self .reformat (name , ignore_errors = True )), original , loc , noqa_able = True , endpoint = False )
1560- for final_check in self .final_checks :
1561- final_check ()
15621557
15631558 def pickle_cache (self , original , cache_path , include_incremental = True ):
15641559 """Pickle the pyparsing cache for original to cache_path."""
@@ -1838,11 +1833,15 @@ def parse(
18381833 with logger .gather_parsing_stats ():
18391834 try :
18401835 pre_procd = self .pre (inputstring , keep_state = keep_state , ** preargs )
1841- if isinstance (parser , tuple ):
1842- init_parser , line_parser = parser
1843- parsed = self .parse_line_by_line (init_parser , line_parser , pre_procd )
1844- else :
1845- parsed = parse (parser , pre_procd , inner = False )
1836+ # handle module-level scope
1837+ with self .add_to_parsing_context ({
1838+ "scope" : self .get_empty_scope (inner = keep_state ),
1839+ }):
1840+ if isinstance (parser , tuple ):
1841+ init_parser , line_parser = parser
1842+ parsed = self .parse_line_by_line (init_parser , line_parser , pre_procd )
1843+ else :
1844+ parsed = parse (parser , pre_procd , inner = False )
18461845 out = self .post (parsed , keep_state = keep_state , ** postargs )
18471846 except ParseBaseException as err :
18481847 raise self .make_parse_err (err )
@@ -4643,11 +4642,12 @@ def {func_name}({iter_var}):
46434642 def get_parent_expr_setnames (self ):
46444643 """Get all expr_setnames in parent contexts, but not the current context."""
46454644 expr_setname_context = self .current_parsing_context ("expr_setnames" )
4646- parent_context = expr_setname_context ["parent" ]
46474645 parent_setnames = set ()
4648- while parent_context :
4649- parent_setnames |= parent_context ["new_names" ]
4650- parent_context = parent_context ["parent" ]
4646+ if expr_setname_context is not None :
4647+ parent_context = expr_setname_context ["parent" ]
4648+ while parent_context :
4649+ parent_setnames |= parent_context ["new_names" ]
4650+ parent_context = parent_context ["parent" ]
46514651 return parent_setnames
46524652
46534653 def handle_expr_scope_closure (self , name , loc ):
@@ -5303,7 +5303,7 @@ def current_parsing_context(self, name, default=None):
53035303 return default
53045304
53055305 @contextmanager
5306- def add_to_parsing_context (self , name_obj_dict , callbacks_keys_dict = None ):
5306+ def add_to_parsing_context (self , name_obj_dict ):
53075307 """Put all the given objects on their respective parsing context stacks."""
53085308 for name , obj in name_obj_dict .items ():
53095309 self .parsing_context [name ].append (obj )
@@ -5312,11 +5312,9 @@ def add_to_parsing_context(self, name_obj_dict, callbacks_keys_dict=None):
53125312 finally :
53135313 for name in name_obj_dict :
53145314 popped_ctx = self .parsing_context [name ].pop ()
5315- if callbacks_keys_dict is not None :
5316- callbacks_key = callbacks_keys_dict .get (name )
5317- if callbacks_key is not None :
5318- for callback in popped_ctx [callbacks_key ]:
5319- callback ()
5315+ if "callbacks" in popped_ctx :
5316+ for callback in popped_ctx ["callbacks" ]:
5317+ callback ()
53205318
53215319 def funcname_typeparams_handle (self , tokens ):
53225320 """Handle function names with type parameters."""
@@ -5584,7 +5582,6 @@ def has_expr_setname_manage(self, original, loc, item):
55845582 "callbacks" : [],
55855583 "loc" : loc ,
55865584 }},
5587- callbacks_keys_dict = {"expr_setnames" : "callbacks" },
55885585 ):
55895586 yield
55905587
@@ -5788,7 +5785,10 @@ def name_handle(self, original, loc, tokens, assign=False, outer_setname=False,
57885785 and name not in self .get_parent_expr_setnames ()
57895786 ))
57905787 ):
5791- self .final_checks .append (partial (self .check_undefined_name , original , loc , name , scope , self .outer_ln ))
5788+ parent_scope = scope
5789+ while parent_scope ["parent" ] is not None :
5790+ parent_scope = parent_scope ["parent" ]
5791+ parent_scope ["callbacks" ].append (partial (self .check_undefined_name , original , loc , name , scope , self .outer_ln ))
57925792
57935793 # only mark as final after all checks pass
57945794 if is_final :
0 commit comments