@@ -313,7 +313,6 @@ def add_implicit_module_attrs(self, file_node: MypyFile) -> None:
313313 self .add_symbol (name , var , None )
314314 else :
315315 self .add_symbol (name , PlaceholderNode (self .qualified_name (name ), file_node ), None )
316- self .defer ()
317316
318317 def prepare_file (self , file_node : MypyFile ) -> None :
319318 """Prepare a freshly parsed file for semantic analysis."""
@@ -848,7 +847,12 @@ def visit_class_def(self, defn: ClassDef) -> None:
848847 def analyze_class (self , defn : ClassDef ) -> None :
849848 fullname = self .qualified_name (defn .name )
850849 if not defn .info and not self .is_core_builtin_class (defn ):
851- self .add_symbol (defn .name , PlaceholderNode (fullname , defn , True ), defn )
850+ # Add placeholder so that self-references in base classes can be
851+ # resolved. We don't want this to cause a deferral, since if there
852+ # are no incomplete references, we'll replace this with a TypeInfo
853+ # before returning.
854+ self .add_symbol (defn .name , PlaceholderNode (fullname , defn , True ), defn ,
855+ can_defer = False )
852856
853857 tag = self .track_incomplete_refs ()
854858
@@ -3900,7 +3904,11 @@ def lookup_qualified(self, name: str, ctx: Context,
39003904 return None
39013905
39023906 def defer (self ) -> None :
3903- """Defer current analysis target to be analyzed again."""
3907+ """Defer current analysis target to be analyzed again.
3908+
3909+ This must be called if something in the current target is
3910+ incomplete or has a placeholder node.
3911+ """
39043912 self .deferred = True
39053913
39063914 def track_incomplete_refs (self ) -> Tag :
@@ -4115,7 +4123,8 @@ def current_symbol_kind(self) -> int:
41154123 return kind
41164124
41174125 def add_symbol (self , name : str , node : SymbolNode , context : Optional [Context ],
4118- module_public : bool = True , module_hidden : bool = False ) -> bool :
4126+ module_public : bool = True , module_hidden : bool = False ,
4127+ can_defer : bool = True ) -> bool :
41194128 """Add symbol to the currently active symbol table.
41204129
41214130 Generally additions to symbol table should go through this method or
@@ -4124,6 +4133,8 @@ def add_symbol(self, name: str, node: SymbolNode, context: Optional[Context],
41244133
41254134 Return True if we actually added the symbol, or False if we refused to do so
41264135 (because something is not ready).
4136+
4137+ If can_defer is True, defer current target if adding a placeholder.
41274138 """
41284139 if self .is_func_scope ():
41294140 kind = LDEF
@@ -4135,7 +4146,7 @@ def add_symbol(self, name: str, node: SymbolNode, context: Optional[Context],
41354146 node ,
41364147 module_public = module_public ,
41374148 module_hidden = module_hidden )
4138- return self .add_symbol_table_node (name , symbol , context )
4149+ return self .add_symbol_table_node (name , symbol , context , can_defer )
41394150
41404151 def add_symbol_skip_local (self , name : str , node : SymbolNode ) -> None :
41414152 """Same as above, but skipping the local namespace.
@@ -4175,21 +4186,26 @@ def is_global_or_nonlocal(self, name: str) -> bool:
41754186 or name in self .nonlocal_decls [- 1 ]))
41764187
41774188 def add_symbol_table_node (self , name : str , symbol : SymbolTableNode ,
4178- context : Optional [Context ] = None ) -> bool :
4189+ context : Optional [Context ] = None ,
4190+ can_defer : bool = True ) -> bool :
41794191 """Add symbol table node to the currently active symbol table.
41804192
41814193 Return True if we actually added the symbol, or False if we refused to do so
41824194 (because something is not ready).
4195+
4196+ If can_defer is True, defer current target if adding a placeholder.
41834197 """
41844198 names = self .current_symbol_table ()
41854199 existing = names .get (name )
4200+ if isinstance (symbol .node , PlaceholderNode ) and can_defer :
4201+ self .defer ()
41864202 if (existing is not None
41874203 and context is not None
41884204 and (not isinstance (existing .node , PlaceholderNode )
4189- or isinstance (symbol .node , PlaceholderNode ) and
4190- # Allow replacing becomes_typeinfo=False with becomes_typeinfo=True.
4191- # This can happen for type aliases and NewTypes.
4192- not symbol .node .becomes_typeinfo )):
4205+ or ( isinstance (symbol .node , PlaceholderNode ) and
4206+ # Allow replacing becomes_typeinfo=False with becomes_typeinfo=True.
4207+ # This can happen for type aliases and NewTypes.
4208+ not symbol .node .becomes_typeinfo ) )):
41934209 # There is an existing node, so this may be a redefinition.
41944210 # If the new node points to the same node as the old one,
41954211 # or if both old and new nodes are placeholders, we don't
0 commit comments