152
152
153
153
# Special cased built-in classes that are needed for basic functionality and need to be
154
154
# available very early on.
155
- CORE_BUILTIN_CLASSES = ['object' , 'bool' ] # type: Final
155
+ CORE_BUILTIN_CLASSES = ['object' , 'bool' , 'tuple' ] # type: Final
156
156
157
157
158
158
# Used for tracking incomplete references
@@ -390,6 +390,8 @@ def refresh_top_level(self, file_node: MypyFile) -> None:
390
390
self .recurse_into_functions = False
391
391
for d in file_node .defs :
392
392
self .accept (d )
393
+ if file_node .fullname () == 'typing' :
394
+ self .add_builtin_aliases (file_node )
393
395
394
396
@contextmanager
395
397
def file_context (self , file_node : MypyFile , fnam : str , options : Options ,
@@ -432,15 +434,19 @@ def file_context(self, file_node: MypyFile, fnam: str, options: Options,
432
434
del self .options
433
435
434
436
def visit_func_def (self , defn : FuncDef ) -> None :
435
- self .add_func_to_symbol_table (defn )
437
+ if not defn .is_decorated and not defn .is_overload :
438
+ self .add_func_to_symbol_table (defn )
436
439
437
440
if not self .recurse_into_functions :
438
441
return
439
442
440
443
with self .scope .function_scope (defn ):
441
444
self ._visit_func_def (defn )
442
445
443
- def add_func_to_symbol_table (self , func : FuncDef ) -> None :
446
+ def add_func_to_symbol_table (self , func : Union [FuncDef , OverloadedFuncDef ]) -> None :
447
+ if self .is_class_scope ():
448
+ assert self .type is not None
449
+ func .info = self .type
444
450
func ._fullname = self .qualified_name (func .name ())
445
451
self .add_symbol (func .name (), func , func )
446
452
@@ -548,8 +554,11 @@ def update_function_type_variables(self, fun_type: CallableType, defn: FuncItem)
548
554
fun_type .variables = a .bind_function_type_variables (fun_type , defn )
549
555
550
556
def visit_overloaded_func_def (self , defn : OverloadedFuncDef ) -> None :
557
+ self .add_func_to_symbol_table (defn )
558
+
551
559
if not self .recurse_into_functions :
552
560
return
561
+
553
562
# NB: Since _visit_overloaded_func_def will call accept on the
554
563
# underlying FuncDefs, the function might get entered twice.
555
564
# This is fine, though, because only the outermost function is
@@ -580,7 +589,7 @@ def _visit_overloaded_func_def(self, defn: OverloadedFuncDef) -> None:
580
589
# This is an a normal overload. Find the item signatures, the
581
590
# implementation (if outside a stub), and any missing @overload
582
591
# decorators.
583
- types , impl , non_overload_indexes = self .find_overload_sigs_and_impl (defn )
592
+ types , impl , non_overload_indexes = self .analyze_overload_sigs_and_impl (defn )
584
593
defn .impl = impl
585
594
if non_overload_indexes :
586
595
self .handle_missing_overload_decorators (defn , non_overload_indexes ,
@@ -606,15 +615,9 @@ def _visit_overloaded_func_def(self, defn: OverloadedFuncDef) -> None:
606
615
self .process_final_in_overload (defn )
607
616
self .process_static_or_class_method_in_overload (defn )
608
617
609
- # TODO: Use add_symbol or similar below (this is inconsistent)
610
- if self .is_class_scope ():
611
- assert self .type is not None
612
- self .type .names [defn .name ()] = SymbolTableNode (MDEF , defn )
613
- defn .info = self .type
614
- elif self .is_func_scope ():
615
- self .add_local (defn , defn )
618
+ self .add_symbol (defn .name (), defn , defn )
616
619
617
- def find_overload_sigs_and_impl (
620
+ def analyze_overload_sigs_and_impl (
618
621
self ,
619
622
defn : OverloadedFuncDef ) -> Tuple [List [CallableType ],
620
623
Optional [OverloadPart ],
@@ -1165,10 +1168,11 @@ def analyze_class_typevar_declaration(self, base: Type) -> Optional[TypeVarList]
1165
1168
sym .node .fullname () == 'typing_extensions.Protocol' and base .args ):
1166
1169
tvars = [] # type: TypeVarList
1167
1170
for arg in unbound .args :
1171
+ tag = self .track_incomplete_refs ()
1168
1172
tvar = self .analyze_unbound_tvar (arg )
1169
1173
if tvar :
1170
1174
tvars .append (tvar )
1171
- else :
1175
+ elif not self . found_incomplete_ref ( tag ) :
1172
1176
self .fail ('Free type variable expected in %s[...]' %
1173
1177
sym .node .name (), base )
1174
1178
return tvars
@@ -1216,7 +1220,7 @@ def prepare_class_def(self, defn: ClassDef, info: Optional[TypeInfo] = None) ->
1216
1220
info = info or self .make_empty_type_info (defn )
1217
1221
defn .info = info
1218
1222
info .defn = defn
1219
- if self .is_module_scope ():
1223
+ if not self .is_func_scope ():
1220
1224
info ._fullname = self .qualified_name (defn .name )
1221
1225
else :
1222
1226
info ._fullname = info .name ()
@@ -2757,6 +2761,9 @@ def process_module_assignment(self, lvals: List[Lvalue], rval: Expression,
2757
2761
lnode .node = rnode .node
2758
2762
2759
2763
def visit_decorator (self , dec : Decorator ) -> None :
2764
+ if not dec .is_overload :
2765
+ self .add_symbol (dec .name (), dec , dec )
2766
+ dec .func ._fullname = self .qualified_name (dec .name ())
2760
2767
for d in dec .decorators :
2761
2768
d .accept (self )
2762
2769
removed = [] # type: List[int]
@@ -3362,7 +3369,9 @@ def visit_index_expr(self, expr: IndexExpr) -> None:
3362
3369
# may be analysing a type alias definition rvalue. The error will be
3363
3370
# reported elsewhere if it is not the case.
3364
3371
typearg2 = self .anal_type (typearg , allow_unbound_tvars = True )
3365
- assert typearg2 is not None # TODO: Deal with None return values
3372
+ if typearg2 is None :
3373
+ self .defer ()
3374
+ return
3366
3375
types .append (typearg2 )
3367
3376
expr .analyzed = TypeApplication (expr .base , types )
3368
3377
expr .analyzed .line = expr .line
@@ -3726,17 +3735,23 @@ def add_builtin_aliases(self, tree: MypyFile) -> None:
3726
3735
assert tree .fullname () == 'typing'
3727
3736
for alias , target_name in type_aliases .items ():
3728
3737
name = alias .split ('.' )[- 1 ]
3738
+ if name in tree .names :
3739
+ continue
3740
+ tag = self .track_incomplete_refs ()
3729
3741
n = self .lookup_fully_qualified_or_none (target_name )
3730
3742
if n :
3743
+ # Found built-in class target. Create alias.
3731
3744
target = self .named_type_or_none (target_name , [])
3732
3745
assert target is not None
3733
3746
alias_node = TypeAlias (target , alias , line = - 1 , column = - 1 , # there is no context
3734
3747
no_args = True , normalized = True )
3735
- tree .names [name ] = SymbolTableNode (GDEF , alias_node )
3748
+ self .add_symbol (name , alias_node , tree )
3749
+ elif self .found_incomplete_ref (tag ):
3750
+ # Built-in class target may not ready yet -- defer.
3751
+ self .mark_incomplete (name )
3736
3752
else :
3737
- # Built-in target not defined, remove the original fake
3738
- # definition to trigger a better error message.
3739
- tree .names .pop (name , None )
3753
+ # Test fixtures may be missing some builtin classes, which is okay.
3754
+ pass
3740
3755
3741
3756
def lookup_fully_qualified (self , name : str ) -> SymbolTableNode :
3742
3757
"""Lookup a fully qualified name.
@@ -3769,7 +3784,11 @@ def lookup_fully_qualified_or_none(self, fullname: str) -> Optional[SymbolTableN
3769
3784
if module not in self .modules :
3770
3785
return None
3771
3786
filenode = self .modules [module ]
3772
- return filenode .names .get (name )
3787
+ result = filenode .names .get (name )
3788
+ if result is None and self .is_incomplete_namespace (module ):
3789
+ # TODO: More explicit handling of incomplete refs?
3790
+ self .record_incomplete_ref ()
3791
+ return result
3773
3792
3774
3793
def qualified_name (self , n : str ) -> str :
3775
3794
if self .type is not None :
0 commit comments