125125 'builtins.bytearray' : 'builtins.str' ,
126126})
127127
128- # When analyzing a function, should we analyze the whole function in one go, or
129- # should we only perform one phase of the analysis? The latter is used for
130- # nested functions. In the first phase we add the function to the symbol table
131- # but don't process body. In the second phase we process function body. This
132- # way we can have mutually recursive nested functions.
133- FUNCTION_BOTH_PHASES = 0 # type: Final # Everything in one go
134- FUNCTION_FIRST_PHASE_POSTPONE_SECOND = 1 # type: Final # Add to symbol table but postpone body
135- FUNCTION_SECOND_PHASE = 2 # type: Final # Only analyze body
136-
137128# Map from the full name of a missing definition to the test fixture (under
138129# test-data/unit/fixtures/) that provides the definition. This is used for
139130# generating better error messages when running mypy tests only.
@@ -193,14 +184,6 @@ class NewSemanticAnalyzer(NodeVisitor[None],
193184 # Stack of functions being analyzed
194185 function_stack = None # type: List[FuncItem]
195186
196- # Status of postponing analysis of nested function bodies. By using this we
197- # can have mutually recursive nested functions. Values are FUNCTION_x
198- # constants. Note that separate phasea are not used for methods.
199- postpone_nested_functions_stack = None # type: List[int]
200- # Postponed functions collected if
201- # postpone_nested_functions_stack[-1] == FUNCTION_FIRST_PHASE_POSTPONE_SECOND.
202- postponed_functions_stack = None # type: List[List[Node]]
203-
204187 loop_depth = 0 # Depth of breakable loops
205188 cur_mod_id = '' # Current module id (or None) (phase 2)
206189 is_stub_file = False # Are we analyzing a stub file?
@@ -228,6 +211,11 @@ def __init__(self,
228211 errors: Report analysis errors using this instance
229212 """
230213 self .locals = [None ]
214+ # Saved namespaces from previous iteration. Every top-level function/method body is
215+ # analyzed in several iterations until all names are resolved. We need to save
216+ # the local namespaces for the top level function and all nested functions between
217+ # these iterations. See also semanal_main.process_top_level_function().
218+ self .saved_locals = {} # type: Dict[FuncItem, SymbolTable]
231219 self .imports = set ()
232220 self .type = None
233221 self .type_stack = []
@@ -243,8 +231,6 @@ def __init__(self,
243231 # missing name in these namespaces, we need to defer the current analysis target,
244232 # since it's possible that the name will be there once the namespace is complete.
245233 self .incomplete_namespaces = incomplete_namespaces
246- self .postpone_nested_functions_stack = [FUNCTION_BOTH_PHASES ]
247- self .postponed_functions_stack = []
248234 self .all_exports = [] # type: List[str]
249235 # Map from module id to list of explicitly exported names (i.e. names in __all__).
250236 self .export_map = {} # type: Dict[str, List[str]]
@@ -451,67 +437,56 @@ def add_func_to_symbol_table(self, func: Union[FuncDef, OverloadedFuncDef]) -> N
451437 self .add_symbol (func .name (), func , func )
452438
453439 def _visit_func_def (self , defn : FuncDef ) -> None :
454- phase_info = self .postpone_nested_functions_stack [- 1 ]
455- if phase_info != FUNCTION_SECOND_PHASE :
456- self .function_stack .append (defn )
457- # First phase of analysis for function.
458- if not defn ._fullname :
459- defn ._fullname = self .qualified_name (defn .name ())
460- if defn .type :
461- assert isinstance (defn .type , CallableType )
462- self .update_function_type_variables (defn .type , defn )
463- self .function_stack .pop ()
440+ self .function_stack .append (defn )
464441
465- defn .is_conditional = self .block_depth [- 1 ] > 0
442+ if defn .type :
443+ assert isinstance (defn .type , CallableType )
444+ self .update_function_type_variables (defn .type , defn )
445+ self .function_stack .pop ()
466446
467- if self .is_class_scope ():
468- # Method definition
469- assert self .type is not None
470- defn .info = self .type
471- if defn .type is not None and defn .name () in ('__init__' , '__init_subclass__' ):
472- assert isinstance (defn .type , CallableType )
473- if isinstance (defn .type .ret_type , AnyType ):
474- defn .type = defn .type .copy_modified (ret_type = NoneTyp ())
475- self .prepare_method_signature (defn , self .type )
476-
477- # Analyze function signature and initializers in the first phase
478- # (at least this mirrors what happens at runtime).
479- with self .tvar_scope_frame (self .tvar_scope .method_frame ()):
480- if defn .type :
481- self .check_classvar_in_signature (defn .type )
447+ defn .is_conditional = self .block_depth [- 1 ] > 0
448+
449+ if self .is_class_scope ():
450+ # Method definition
451+ assert self .type is not None
452+ defn .info = self .type
453+ if defn .type is not None and defn .name () in ('__init__' , '__init_subclass__' ):
454+ assert isinstance (defn .type , CallableType )
455+ if isinstance (defn .type .ret_type , AnyType ):
456+ defn .type = defn .type .copy_modified (ret_type = NoneTyp ())
457+ self .prepare_method_signature (defn , self .type )
458+
459+ # Analyze function signature and initializers first.
460+ with self .tvar_scope_frame (self .tvar_scope .method_frame ()):
461+ if defn .type :
462+ self .check_classvar_in_signature (defn .type )
463+ assert isinstance (defn .type , CallableType )
464+ # Signature must be analyzed in the surrounding scope so that
465+ # class-level imported names and type variables are in scope.
466+ analyzer = self .type_analyzer ()
467+ defn .type = analyzer .visit_callable_type (defn .type , nested = False )
468+ self .add_type_alias_deps (analyzer .aliases_used )
469+ self .check_function_signature (defn )
470+ if isinstance (defn , FuncDef ):
482471 assert isinstance (defn .type , CallableType )
483- # Signature must be analyzed in the surrounding scope so that
484- # class-level imported names and type variables are in scope.
485- analyzer = self .type_analyzer ()
486- defn .type = analyzer .visit_callable_type (defn .type , nested = False )
487- self .add_type_alias_deps (analyzer .aliases_used )
488- self .check_function_signature (defn )
489- if isinstance (defn , FuncDef ):
490- assert isinstance (defn .type , CallableType )
491- defn .type = set_callable_name (defn .type , defn )
492- for arg in defn .arguments :
493- if arg .initializer :
494- arg .initializer .accept (self )
495-
496- if phase_info == FUNCTION_FIRST_PHASE_POSTPONE_SECOND :
497- # Postpone this function (for the second phase).
498- self .postponed_functions_stack [- 1 ].append (defn )
499- return
500- if phase_info != FUNCTION_FIRST_PHASE_POSTPONE_SECOND :
501- # Second phase of analysis for function.
502- self .analyze_function (defn )
503- if defn .is_coroutine and isinstance (defn .type , CallableType ):
504- if defn .is_async_generator :
505- # Async generator types are handled elsewhere
506- pass
507- else :
508- # A coroutine defined as `async def foo(...) -> T: ...`
509- # has external return type `Coroutine[Any, Any, T]`.
510- any_type = AnyType (TypeOfAny .special_form )
511- ret_type = self .named_type_or_none ('typing.Coroutine' ,
512- [any_type , any_type , defn .type .ret_type ])
513- assert ret_type is not None , "Internal error: typing.Coroutine not found"
514- defn .type = defn .type .copy_modified (ret_type = ret_type )
472+ defn .type = set_callable_name (defn .type , defn )
473+ for arg in defn .arguments :
474+ if arg .initializer :
475+ arg .initializer .accept (self )
476+
477+ self .analyze_function (defn )
478+ if defn .is_coroutine and isinstance (defn .type , CallableType ):
479+ if defn .is_async_generator :
480+ # Async generator types are handled elsewhere
481+ pass
482+ else :
483+ # A coroutine defined as `async def foo(...) -> T: ...`
484+ # has external return type `Coroutine[Any, Any, T]`.
485+ any_type = AnyType (TypeOfAny .special_form )
486+ ret_type = self .named_type_or_none ('typing.Coroutine' ,
487+ [any_type , any_type , defn .type .ret_type ])
488+ assert ret_type is not None , "Internal error: typing.Coroutine not found"
489+ defn .type = defn .type .copy_modified (ret_type = ret_type )
515490
516491 def prepare_method_signature (self , func : FuncDef , info : TypeInfo ) -> None :
517492 """Check basic signature validity and tweak annotation of self/cls argument."""
@@ -630,6 +605,10 @@ def analyze_overload_sigs_and_impl(
630605 types = []
631606 non_overload_indexes = []
632607 impl = None # type: Optional[OverloadPart]
608+ # TODO: This is really bad, we should not modify defn.items neither here nor above.
609+ if defn .impl :
610+ # We are visiting this second time.
611+ defn .items .append (defn .impl )
633612 for i , item in enumerate (defn .items ):
634613 if i != 0 :
635614 # Assume that the first item was already visited
@@ -780,7 +759,7 @@ def analyze_function(self, defn: FuncItem) -> None:
780759 a = self .type_analyzer ()
781760 a .bind_function_type_variables (cast (CallableType , defn .type ), defn )
782761 self .function_stack .append (defn )
783- self .enter ()
762+ self .enter (defn )
784763 for arg in defn .arguments :
785764 self .add_local (arg .variable , defn )
786765
@@ -790,18 +769,7 @@ def analyze_function(self, defn: FuncItem) -> None:
790769 if is_method and not defn .is_static and not defn .is_class and defn .arguments :
791770 defn .arguments [0 ].variable .is_self = True
792771
793- # First analyze body of the function but ignore nested functions.
794- self .postpone_nested_functions_stack .append (FUNCTION_FIRST_PHASE_POSTPONE_SECOND )
795- self .postponed_functions_stack .append ([])
796772 defn .body .accept (self )
797-
798- # Analyze nested functions (if any) as a second phase.
799- self .postpone_nested_functions_stack [- 1 ] = FUNCTION_SECOND_PHASE
800- for postponed in self .postponed_functions_stack [- 1 ]:
801- postponed .accept (self )
802- self .postpone_nested_functions_stack .pop ()
803- self .postponed_functions_stack .pop ()
804-
805773 self .leave ()
806774 self .function_stack .pop ()
807775
@@ -977,12 +945,10 @@ def enter_class(self, info: TypeInfo) -> None:
977945 self .type_stack .append (self .type )
978946 self .locals .append (None ) # Add class scope
979947 self .block_depth .append (- 1 ) # The class body increments this to 0
980- self .postpone_nested_functions_stack .append (FUNCTION_BOTH_PHASES )
981948 self .type = info
982949
983950 def leave_class (self ) -> None :
984951 """ Restore analyzer state. """
985- self .postpone_nested_functions_stack .pop ()
986952 self .block_depth .pop ()
987953 self .locals .pop ()
988954 self .type = self .type_stack .pop ()
@@ -3797,8 +3763,17 @@ def qualified_name(self, n: str) -> str:
37973763 base = self .cur_mod_id
37983764 return base + '.' + n
37993765
3800- def enter (self ) -> None :
3801- self .locals .append (SymbolTable ())
3766+ def enter (self , function : Optional [FuncItem ] = None ) -> None :
3767+ """Enter the function scope.
3768+
3769+ The argument can be omitted for temporary scopes (like comprehensions
3770+ and generator expressions) that can't have incomplete definitions.
3771+ """
3772+ if function :
3773+ names = self .saved_locals .setdefault (function , SymbolTable ())
3774+ else :
3775+ names = SymbolTable ()
3776+ self .locals .append (names )
38023777 self .global_decls .append (set ())
38033778 self .nonlocal_decls .append (set ())
38043779 # -1 since entering block will increment this to 0.
0 commit comments