Skip to content
4 changes: 3 additions & 1 deletion mypy/expandtype.py
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,9 @@ def visit_tuple_type(self, t: TupleType) -> Type:
if isinstance(item, UnpackType):
unpacked = get_proper_type(item.type)
if isinstance(unpacked, Instance):
assert unpacked.type.fullname == "builtins.tuple"
# expand_type() may be called during semantic analysis, before invalid unpacks are fixed.
if unpacked.type.fullname != "builtins.tuple":
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a comment above this line explaining that expand_type() may be called during semantic analysis, before invalid unpacks are fixed.

return t.partial_fallback.accept(self)
if t.partial_fallback.type.fullname != "builtins.tuple":
# If it is a subtype (like named tuple) we need to preserve it,
# this essentially mimics the logic in tuple_fallback().
Expand Down
14 changes: 14 additions & 0 deletions test-data/unit/check-type-aliases.test
Original file line number Diff line number Diff line change
Expand Up @@ -1237,6 +1237,20 @@ Ta2 = TypeAliasType("Ta2", None, type_params=(Unpack[Ts],)) # E: Free type vari

[builtins fixtures/tuple.pyi]

[case testGenericTypeAliasArgOfTypeAliasIsUnpackedTuple-xfail]
from typing_extensions import TypeAlias
from typing import TypeVarTuple, Unpack

Ts = TypeVarTuple('Ts')

TA: TypeAlias = tuple[Unpack[Ts]]

# For Python 3.10, error: Invalid syntax
# For other Python, error: "list[int]" cannot be unpacked (must be tuple or TypeVarTuple)
v1: TA[*list[int]]
v2: TA[Unpack[list[int]]]
[builtins fixtures/tuple.pyi]

[case testAliasInstanceNameClash]
from lib import func
class A: ...
Expand Down
Loading