4
4
5
5
from mypy .types import (
6
6
Type , AnyType , CallableType , Overloaded , NoneTyp , Void , TypeVarDef ,
7
- TupleType , Instance , TypeVarType , ErasedType , UnionType ,
7
+ TupleType , Instance , TypeVarId , TypeVarType , ErasedType , UnionType ,
8
8
PartialType , DeletedType , UnboundType , UninhabitedType , TypeType
9
9
)
10
10
from mypy .nodes import (
22
22
import mypy .checker
23
23
from mypy import types
24
24
from mypy .sametypes import is_same_type
25
- from mypy .replacetvars import replace_func_type_vars
25
+ from mypy .erasetype import replace_meta_vars
26
26
from mypy .messages import MessageBuilder
27
27
from mypy import messages
28
28
from mypy .infer import infer_type_arguments , infer_function_type_arguments
34
34
from mypy .semanal import self_type
35
35
from mypy .constraints import get_actual_type
36
36
from mypy .checkstrformat import StringFormatterChecker
37
+ from mypy .expandtype import expand_type
37
38
38
39
from mypy import experiments
39
40
@@ -234,6 +235,7 @@ def check_call(self, callee: Type, args: List[Node],
234
235
lambda i : self .accept (args [i ]))
235
236
236
237
if callee .is_generic ():
238
+ callee = freshen_generic_callable (callee )
237
239
callee = self .infer_function_type_arguments_using_context (
238
240
callee , context )
239
241
callee = self .infer_function_type_arguments (
@@ -394,12 +396,12 @@ def infer_function_type_arguments_using_context(
394
396
ctx = self .chk .type_context [- 1 ]
395
397
if not ctx :
396
398
return callable
397
- # The return type may have references to function type variables that
399
+ # The return type may have references to type metavariables that
398
400
# we are inferring right now. We must consider them as indeterminate
399
401
# and they are not potential results; thus we replace them with the
400
402
# special ErasedType type. On the other hand, class type variables are
401
403
# valid results.
402
- erased_ctx = replace_func_type_vars (ctx , ErasedType ())
404
+ erased_ctx = replace_meta_vars (ctx , ErasedType ())
403
405
ret_type = callable .ret_type
404
406
if isinstance (ret_type , TypeVarType ):
405
407
if ret_type .values or (not isinstance (ctx , Instance ) or
@@ -1264,15 +1266,16 @@ def visit_set_expr(self, e: SetExpr) -> Type:
1264
1266
def check_list_or_set_expr (self , items : List [Node ], fullname : str ,
1265
1267
tag : str , context : Context ) -> Type :
1266
1268
# Translate into type checking a generic function call.
1267
- tv = TypeVarType ('T' , - 1 , [], self .chk .object_type ())
1269
+ tvdef = TypeVarDef ('T' , - 1 , [], self .chk .object_type ())
1270
+ tv = TypeVarType (tvdef )
1268
1271
constructor = CallableType (
1269
1272
[tv ],
1270
1273
[nodes .ARG_STAR ],
1271
1274
[None ],
1272
1275
self .chk .named_generic_type (fullname , [tv ]),
1273
1276
self .named_type ('builtins.function' ),
1274
1277
name = tag ,
1275
- variables = [TypeVarDef ( 'T' , - 1 , None , self . chk . object_type ()) ])
1278
+ variables = [tvdef ])
1276
1279
return self .check_call (constructor ,
1277
1280
items ,
1278
1281
[nodes .ARG_POS ] * len (items ), context )[0 ]
@@ -1301,20 +1304,21 @@ def visit_tuple_expr(self, e: TupleExpr) -> Type:
1301
1304
1302
1305
def visit_dict_expr (self , e : DictExpr ) -> Type :
1303
1306
# Translate into type checking a generic function call.
1304
- tv1 = TypeVarType ('KT' , - 1 , [], self .chk .object_type ())
1305
- tv2 = TypeVarType ('VT' , - 2 , [], self .chk .object_type ())
1307
+ ktdef = TypeVarDef ('KT' , - 1 , [], self .chk .object_type ())
1308
+ vtdef = TypeVarDef ('VT' , - 2 , [], self .chk .object_type ())
1309
+ kt = TypeVarType (ktdef )
1310
+ vt = TypeVarType (vtdef )
1306
1311
# The callable type represents a function like this:
1307
1312
#
1308
1313
# def <unnamed>(*v: Tuple[kt, vt]) -> Dict[kt, vt]: ...
1309
1314
constructor = CallableType (
1310
- [TupleType ([tv1 , tv2 ], self .named_type ('builtins.tuple' ))],
1315
+ [TupleType ([kt , vt ], self .named_type ('builtins.tuple' ))],
1311
1316
[nodes .ARG_STAR ],
1312
1317
[None ],
1313
- self .chk .named_generic_type ('builtins.dict' , [tv1 , tv2 ]),
1318
+ self .chk .named_generic_type ('builtins.dict' , [kt , vt ]),
1314
1319
self .named_type ('builtins.function' ),
1315
1320
name = '<list>' ,
1316
- variables = [TypeVarDef ('KT' , - 1 , None , self .chk .object_type ()),
1317
- TypeVarDef ('VT' , - 2 , None , self .chk .object_type ())])
1321
+ variables = [ktdef , vtdef ])
1318
1322
# Synthesize function arguments.
1319
1323
args = [] # type: List[Node]
1320
1324
for key , value in e .items :
@@ -1360,7 +1364,7 @@ def infer_lambda_type_using_context(self, e: FuncExpr) -> CallableType:
1360
1364
# they must be considered as indeterminate. We use ErasedType since it
1361
1365
# does not affect type inference results (it is for purposes like this
1362
1366
# only).
1363
- ctx = replace_func_type_vars (ctx , ErasedType ())
1367
+ ctx = replace_meta_vars (ctx , ErasedType ())
1364
1368
1365
1369
callable_ctx = cast (CallableType , ctx )
1366
1370
@@ -1438,15 +1442,16 @@ def check_generator_or_comprehension(self, gen: GeneratorExpr,
1438
1442
1439
1443
# Infer the type of the list comprehension by using a synthetic generic
1440
1444
# callable type.
1441
- tv = TypeVarType ('T' , - 1 , [], self .chk .object_type ())
1445
+ tvdef = TypeVarDef ('T' , - 1 , [], self .chk .object_type ())
1446
+ tv = TypeVarType (tvdef )
1442
1447
constructor = CallableType (
1443
1448
[tv ],
1444
1449
[nodes .ARG_POS ],
1445
1450
[None ],
1446
1451
self .chk .named_generic_type (type_name , [tv ]),
1447
1452
self .chk .named_type ('builtins.function' ),
1448
1453
name = id_for_messages ,
1449
- variables = [TypeVarDef ( 'T' , - 1 , None , self . chk . object_type ()) ])
1454
+ variables = [tvdef ])
1450
1455
return self .check_call (constructor ,
1451
1456
[gen .left_expr ], [nodes .ARG_POS ], gen )[0 ]
1452
1457
@@ -1456,17 +1461,18 @@ def visit_dictionary_comprehension(self, e: DictionaryComprehension):
1456
1461
1457
1462
# Infer the type of the list comprehension by using a synthetic generic
1458
1463
# callable type.
1459
- key_tv = TypeVarType ('KT' , - 1 , [], self .chk .object_type ())
1460
- value_tv = TypeVarType ('VT' , - 2 , [], self .chk .object_type ())
1464
+ ktdef = TypeVarDef ('KT' , - 1 , [], self .chk .object_type ())
1465
+ vtdef = TypeVarDef ('VT' , - 2 , [], self .chk .object_type ())
1466
+ kt = TypeVarType (ktdef )
1467
+ vt = TypeVarType (vtdef )
1461
1468
constructor = CallableType (
1462
- [key_tv , value_tv ],
1469
+ [kt , vt ],
1463
1470
[nodes .ARG_POS , nodes .ARG_POS ],
1464
1471
[None , None ],
1465
- self .chk .named_generic_type ('builtins.dict' , [key_tv , value_tv ]),
1472
+ self .chk .named_generic_type ('builtins.dict' , [kt , vt ]),
1466
1473
self .chk .named_type ('builtins.function' ),
1467
1474
name = '<dictionary-comprehension>' ,
1468
- variables = [TypeVarDef ('KT' , - 1 , None , self .chk .object_type ()),
1469
- TypeVarDef ('VT' , - 2 , None , self .chk .object_type ())])
1475
+ variables = [ktdef , vtdef ])
1470
1476
return self .check_call (constructor ,
1471
1477
[e .key , e .value ], [nodes .ARG_POS , nodes .ARG_POS ], e )[0 ]
1472
1478
@@ -1775,3 +1781,14 @@ def overload_arg_similarity(actual: Type, formal: Type) -> int:
1775
1781
return 2
1776
1782
# Fall back to a conservative equality check for the remaining kinds of type.
1777
1783
return 2 if is_same_type (erasetype .erase_type (actual ), erasetype .erase_type (formal )) else 0
1784
+
1785
+
1786
+ def freshen_generic_callable (callee : CallableType ) -> CallableType :
1787
+ tvdefs = []
1788
+ tvmap = {} # type: Dict[TypeVarId, Type]
1789
+ for v in callee .variables :
1790
+ tvdef = TypeVarDef .new_unification_variable (v )
1791
+ tvdefs .append (tvdef )
1792
+ tvmap [v .id ] = TypeVarType (tvdef )
1793
+
1794
+ return cast (CallableType , expand_type (callee , tvmap )).copy_modified (variables = tvdefs )
0 commit comments