6
6
Type , AnyType , CallableType , Overloaded , NoneTyp , Void , TypeVarDef ,
7
7
TupleType , Instance , TypeVarId , TypeVarType , ErasedType , UnionType ,
8
8
PartialType , DeletedType , UnboundType , UninhabitedType , TypeType ,
9
- true_only , false_only
9
+ true_only , false_only , is_named_instance
10
10
)
11
11
from mypy .nodes import (
12
12
NameExpr , RefExpr , Var , FuncDef , OverloadedFuncDef , TypeInfo , CallExpr ,
@@ -1408,11 +1408,26 @@ def check_lst_expr(self, items: List[Node], fullname: str,
1408
1408
1409
1409
def visit_tuple_expr (self , e : TupleExpr ) -> Type :
1410
1410
"""Type check a tuple expression."""
1411
- ctx = None # type: TupleType
1412
1411
# Try to determine type context for type inference.
1413
- if isinstance (self .chk .type_context [- 1 ], TupleType ):
1414
- t = self .chk .type_context [- 1 ]
1415
- ctx = t
1412
+ type_context = self .chk .type_context [- 1 ]
1413
+ type_context_items = None
1414
+ if isinstance (type_context , UnionType ):
1415
+ tuples_in_context = [t for t in type_context .items
1416
+ if (isinstance (t , TupleType ) and len (t .items ) == len (e .items )) or
1417
+ is_named_instance (t , 'builtins.tuple' )]
1418
+ if len (tuples_in_context ) == 1 :
1419
+ type_context = tuples_in_context [0 ]
1420
+ else :
1421
+ # There are either no relevant tuples in the Union, or there is
1422
+ # more than one. Either way, we can't decide on a context.
1423
+ pass
1424
+
1425
+ if isinstance (type_context , TupleType ):
1426
+ type_context_items = type_context .items
1427
+ elif is_named_instance (type_context , 'builtins.tuple' ):
1428
+ assert isinstance (type_context , Instance )
1429
+ if type_context .args :
1430
+ type_context_items = [type_context .args [0 ]] * len (e .items )
1416
1431
# NOTE: it's possible for the context to have a different
1417
1432
# number of items than e. In that case we use those context
1418
1433
# items that match a position in e, and we'll worry about type
@@ -1421,7 +1436,7 @@ def visit_tuple_expr(self, e: TupleExpr) -> Type:
1421
1436
# Infer item types. Give up if there's a star expression
1422
1437
# that's not a Tuple.
1423
1438
items = [] # type: List[Type]
1424
- j = 0 # Index into ctx.items ; irrelevant if ctx is None.
1439
+ j = 0 # Index into type_context_items ; irrelevant if type_context_items is none
1425
1440
for i in range (len (e .items )):
1426
1441
item = e .items [i ]
1427
1442
tt = None # type: Type
@@ -1441,10 +1456,10 @@ def visit_tuple_expr(self, e: TupleExpr) -> Type:
1441
1456
# Treat the whole thing as a variable-length tuple.
1442
1457
return self .check_lst_expr (e .items , 'builtins.tuple' , '<tuple>' , e )
1443
1458
else :
1444
- if not ctx or j >= len (ctx . items ):
1459
+ if not type_context_items or j >= len (type_context_items ):
1445
1460
tt = self .accept (item )
1446
1461
else :
1447
- tt = self .accept (item , ctx . items [j ])
1462
+ tt = self .accept (item , type_context_items [j ])
1448
1463
j += 1
1449
1464
self .check_usable_type (tt , e )
1450
1465
items .append (tt )
0 commit comments