17
17
Node , Expression , MypyFile , FuncDef , FuncItem , Decorator , RefExpr , Context , TypeInfo , ClassDef ,
18
18
Block , TypedDictExpr , NamedTupleExpr , AssignmentStmt , IndexExpr , TypeAliasExpr , NameExpr ,
19
19
CallExpr , NewTypeExpr , ForStmt , WithStmt , CastExpr , TypeVarExpr , TypeApplication , Lvalue ,
20
- TupleExpr , RevealTypeExpr , SymbolTableNode , Var , ARG_POS
20
+ TupleExpr , RevealTypeExpr , SymbolTableNode , Var , ARG_POS , OverloadedFuncDef
21
21
)
22
22
from mypy .types import (
23
23
Type , Instance , AnyType , TypeOfAny , CallableType , TupleType , TypeVarType , TypedDictType ,
@@ -85,6 +85,10 @@ def visit_func_def(self, fdef: FuncDef) -> None:
85
85
super ().visit_func_def (fdef )
86
86
self .errors .pop_function ()
87
87
88
+ def visit_overloaded_func_def (self , fdef : OverloadedFuncDef ) -> None :
89
+ self .analyze (fdef .type , fdef )
90
+ super ().visit_overloaded_func_def (fdef )
91
+
88
92
def visit_class_def (self , tdef : ClassDef ) -> None :
89
93
# NamedTuple base classes are validated in check_namedtuple_classdef; we don't have to
90
94
# check them again here.
@@ -116,12 +120,7 @@ def visit_class_def(self, tdef: ClassDef) -> None:
116
120
self .analyze (tdef .analyzed .info .typeddict_type , tdef .analyzed , warn = True )
117
121
elif isinstance (tdef .analyzed , NamedTupleExpr ):
118
122
self .analyze (tdef .analyzed .info .tuple_type , tdef .analyzed , warn = True )
119
- for name in tdef .analyzed .info .names :
120
- sym = tdef .analyzed .info .names [name ]
121
- if isinstance (sym .node , (FuncDef , Decorator )):
122
- self .accept (sym .node )
123
- if isinstance (sym .node , Var ):
124
- self .analyze (sym .node .type , sym .node )
123
+ self .analyze_info (tdef .analyzed .info )
125
124
super ().visit_class_def (tdef )
126
125
127
126
def visit_decorator (self , dec : Decorator ) -> None :
@@ -189,6 +188,10 @@ def visit_assignment_stmt(self, s: AssignmentStmt) -> None:
189
188
analyzed = s .rvalue .analyzed
190
189
if isinstance (analyzed , NewTypeExpr ):
191
190
self .analyze (analyzed .old_type , analyzed )
191
+ if analyzed .info :
192
+ # Currently NewTypes only have __init__, but to be future proof,
193
+ # we analyze all symbols.
194
+ self .analyze_info (analyzed .info )
192
195
if analyzed .info and analyzed .info .mro :
193
196
analyzed .info .mro = [] # Force recomputation
194
197
mypy .semanal .calculate_class_mro (analyzed .info .defn , self .fail_blocker )
@@ -203,12 +206,7 @@ def visit_assignment_stmt(self, s: AssignmentStmt) -> None:
203
206
self .analyze (analyzed .info .typeddict_type , analyzed , warn = True )
204
207
if isinstance (analyzed , NamedTupleExpr ):
205
208
self .analyze (analyzed .info .tuple_type , analyzed , warn = True )
206
- for name in analyzed .info .names :
207
- sym = analyzed .info .names [name ]
208
- if isinstance (sym .node , (FuncDef , Decorator )):
209
- self .accept (sym .node )
210
- if isinstance (sym .node , Var ):
211
- self .analyze (sym .node .type , sym .node )
209
+ self .analyze_info (analyzed .info )
212
210
# We need to pay additional attention to assignments that define a type alias.
213
211
# The resulting type is also stored in the 'type_override' attribute of
214
212
# the corresponding SymbolTableNode.
@@ -255,12 +253,27 @@ def perform_transform(self, node: Union[Node, SymbolTableNode],
255
253
for n in node .target :
256
254
if isinstance (n , NameExpr ) and isinstance (n .node , Var ) and n .node .type :
257
255
n .node .type = transform (n .node .type )
258
- if isinstance (node , (FuncDef , CastExpr , AssignmentStmt , TypeAliasExpr , Var )):
256
+ if isinstance (node , (FuncDef , OverloadedFuncDef , CastExpr , AssignmentStmt ,
257
+ TypeAliasExpr , Var )):
259
258
assert node .type , "Scheduled patch for non-existent type"
260
259
node .type = transform (node .type )
261
260
if isinstance (node , NewTypeExpr ):
262
261
assert node .old_type , "Scheduled patch for non-existent type"
263
262
node .old_type = transform (node .old_type )
263
+ if node .info :
264
+ new_bases = [] # type: List[Instance]
265
+ for b in node .info .bases :
266
+ new_b = transform (b )
267
+ # TODO: this code can be combined with code in second pass.
268
+ if isinstance (new_b , Instance ):
269
+ new_bases .append (new_b )
270
+ elif isinstance (new_b , TupleType ):
271
+ new_bases .append (new_b .fallback )
272
+ else :
273
+ self .fail ("Argument 2 to NewType(...) must be subclassable"
274
+ " (got {})" .format (new_b ), node )
275
+ new_bases .append (self .builtin_type ('object' ))
276
+ node .info .bases = new_bases
264
277
if isinstance (node , TypeVarExpr ):
265
278
if node .upper_bound :
266
279
node .upper_bound = transform (node .upper_bound )
@@ -292,7 +305,7 @@ def perform_transform(self, node: Union[Node, SymbolTableNode],
292
305
new_bases .append (new_base )
293
306
else :
294
307
# Don't fix the NamedTuple bases, they are Instance's intentionally.
295
- # Patch the 'args' just in case, although generic tuple type are
308
+ # Patch the 'args' just in case, although generic tuple types are
296
309
# not supported yet.
297
310
alt_base = Instance (base .type , [transform (a ) for a in base .args ])
298
311
new_bases .append (alt_base )
@@ -339,6 +352,15 @@ def patch() -> None:
339
352
node , warn = False )))
340
353
self .patches .append (patch )
341
354
355
+ def analyze_info (self , info : TypeInfo ) -> None :
356
+ # Similar to above but for nodes with synthetic TypeInfos (NamedTuple and NewType).
357
+ for name in info .names :
358
+ sym = info .names [name ]
359
+ if isinstance (sym .node , (FuncDef , Decorator )):
360
+ self .accept (sym .node )
361
+ if isinstance (sym .node , Var ):
362
+ self .analyze (sym .node .type , sym .node )
363
+
342
364
def make_type_analyzer (self , indicator : Dict [str , bool ]) -> TypeAnalyserPass3 :
343
365
return TypeAnalyserPass3 (self .sem .lookup_qualified ,
344
366
self .sem .lookup_fully_qualified ,
0 commit comments