@@ -568,7 +568,9 @@ def try_analyze_special_unbound_type(self, t: UnboundType, fullname: str) -> Typ
568
568
instance = self .named_type ("builtins.tuple" , [self .anal_type (t .args [0 ])])
569
569
instance .line = t .line
570
570
return instance
571
- return self .tuple_type (self .anal_array (t .args , allow_unpack = True ))
571
+ return self .tuple_type (
572
+ self .anal_array (t .args , allow_unpack = True ), line = t .line , column = t .column
573
+ )
572
574
elif fullname == "typing.Union" :
573
575
items = self .anal_array (t .args )
574
576
return UnionType .make_union (items )
@@ -968,7 +970,10 @@ def visit_type_var_tuple(self, t: TypeVarTupleType) -> Type:
968
970
return t
969
971
970
972
def visit_unpack_type (self , t : UnpackType ) -> Type :
971
- raise NotImplementedError
973
+ if not self .allow_unpack :
974
+ self .fail (message_registry .INVALID_UNPACK_POSITION , t .type , code = codes .VALID_TYPE )
975
+ return AnyType (TypeOfAny .from_error )
976
+ return UnpackType (self .anal_type (t .type ))
972
977
973
978
def visit_parameters (self , t : Parameters ) -> Type :
974
979
raise NotImplementedError ("ParamSpec literals cannot have unbound TypeVars" )
@@ -1364,12 +1369,22 @@ def analyze_callable_type(self, t: UnboundType) -> Type:
1364
1369
assert isinstance (ret , CallableType )
1365
1370
return ret .accept (self )
1366
1371
1372
+ def refers_to_full_names (self , arg : UnboundType , names : Sequence [str ]) -> bool :
1373
+ sym = self .lookup_qualified (arg .name , arg )
1374
+ if sym is not None :
1375
+ if sym .fullname in names :
1376
+ return True
1377
+ return False
1378
+
1367
1379
def analyze_callable_args (
1368
1380
self , arglist : TypeList
1369
1381
) -> tuple [list [Type ], list [ArgKind ], list [str | None ]] | None :
1370
1382
args : list [Type ] = []
1371
1383
kinds : list [ArgKind ] = []
1372
1384
names : list [str | None ] = []
1385
+ seen_unpack = False
1386
+ unpack_types : list [Type ] = []
1387
+ invalid_unpacks = []
1373
1388
for arg in arglist .items :
1374
1389
if isinstance (arg , CallableArgument ):
1375
1390
args .append (arg .typ )
@@ -1390,20 +1405,42 @@ def analyze_callable_args(
1390
1405
if arg .name is not None and kind .is_star ():
1391
1406
self .fail (f"{ arg .constructor } arguments should not have names" , arg )
1392
1407
return None
1393
- elif isinstance (arg , UnboundType ):
1394
- kind = ARG_POS
1395
- # Potentially a unpack.
1396
- sym = self .lookup_qualified (arg .name , arg )
1397
- if sym is not None :
1398
- if sym .fullname in ("typing_extensions.Unpack" , "typing.Unpack" ):
1399
- kind = ARG_STAR
1400
- args .append (arg )
1401
- kinds .append (kind )
1402
- names .append (None )
1408
+ elif (
1409
+ isinstance (arg , UnboundType )
1410
+ and self .refers_to_full_names (arg , ("typing_extensions.Unpack" , "typing.Unpack" ))
1411
+ or isinstance (arg , UnpackType )
1412
+ ):
1413
+ if seen_unpack :
1414
+ # Multiple unpacks, preserve them, so we can give an error later.
1415
+ invalid_unpacks .append (arg )
1416
+ continue
1417
+ seen_unpack = True
1418
+ unpack_types .append (arg )
1419
+ else :
1420
+ if seen_unpack :
1421
+ unpack_types .append (arg )
1422
+ else :
1423
+ args .append (arg )
1424
+ kinds .append (ARG_POS )
1425
+ names .append (None )
1426
+ if seen_unpack :
1427
+ if len (unpack_types ) == 1 :
1428
+ args .append (unpack_types [0 ])
1403
1429
else :
1404
- args .append (arg )
1405
- kinds .append (ARG_POS )
1406
- names .append (None )
1430
+ first = unpack_types [0 ]
1431
+ if isinstance (first , UnpackType ):
1432
+ # UnpackType doesn't have its own line/column numbers,
1433
+ # so use the unpacked type for error messages.
1434
+ first = first .type
1435
+ args .append (
1436
+ UnpackType (self .tuple_type (unpack_types , line = first .line , column = first .column ))
1437
+ )
1438
+ kinds .append (ARG_STAR )
1439
+ names .append (None )
1440
+ for arg in invalid_unpacks :
1441
+ args .append (arg )
1442
+ kinds .append (ARG_STAR )
1443
+ names .append (None )
1407
1444
# Note that arglist below is only used for error context.
1408
1445
check_arg_names (names , [arglist ] * len (args ), self .fail , "Callable" )
1409
1446
check_arg_kinds (kinds , [arglist ] * len (args ), self .fail )
@@ -1713,9 +1750,11 @@ def check_unpacks_in_list(self, items: list[Type]) -> list[Type]:
1713
1750
self .fail ("More than one Unpack in a type is not allowed" , final_unpack )
1714
1751
return new_items
1715
1752
1716
- def tuple_type (self , items : list [Type ]) -> TupleType :
1753
+ def tuple_type (self , items : list [Type ], line : int , column : int ) -> TupleType :
1717
1754
any_type = AnyType (TypeOfAny .special_form )
1718
- return TupleType (items , fallback = self .named_type ("builtins.tuple" , [any_type ]))
1755
+ return TupleType (
1756
+ items , fallback = self .named_type ("builtins.tuple" , [any_type ]), line = line , column = column
1757
+ )
1719
1758
1720
1759
1721
1760
TypeVarLikeList = List [Tuple [str , TypeVarLikeExpr ]]
0 commit comments