diff --git a/mypy/expandtype.py b/mypy/expandtype.py index 5790b717172a..ea0e1e0d9ac4 100644 --- a/mypy/expandtype.py +++ b/mypy/expandtype.py @@ -223,7 +223,7 @@ def visit_instance(self, t: Instance) -> Type: # See: https://github.com/python/mypy/issues/16649 return t.copy_modified(args=args) - if t.type.fullname == "builtins.tuple": + if t.type.fullname == "builtins.tuple" and len(args) > 0: # Normalize Tuple[*Tuple[X, ...], ...] -> Tuple[X, ...] arg = args[0] if isinstance(arg, UnpackType): diff --git a/test-data/unit/check-python312.test b/test-data/unit/check-python312.test index 0521722b47c1..986b24c74cf3 100644 --- a/test-data/unit/check-python312.test +++ b/test-data/unit/check-python312.test @@ -2237,3 +2237,17 @@ class D[*Ts](Generic[Unpack[Us]]): # E: Generic[...] base class is redundant \ # E: Can only use one type var tuple in a class def pass [builtins fixtures/tuple.pyi] + +[case testUnpackEmptyTupleInTypeAliasNoCrash] +# https://github.com/python/mypy/issues/20913 +from typing import Unpack + +class C[*Ts]: + pass + +type T[T, *Ts] = C[*Ts] + +x: T[bool, Unpack[tuple[()]]] +reveal_type(x) # N: Revealed type is "__main__.C[Unpack[builtins.tuple]]" +[builtins fixtures/tuple.pyi] +[typing fixtures/typing-full.pyi]