From d5c817705eacbfdfd974de566c0f52e6eab7e4c4 Mon Sep 17 00:00:00 2001 From: "Kai (Kazuya Ito)" Date: Fri, 30 Jan 2026 05:32:55 +0900 Subject: [PATCH 01/16] Change assertion to conditional check for tuple type --- mypy/expandtype.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mypy/expandtype.py b/mypy/expandtype.py index 7f95b2e25320..81dafc1a6b58 100644 --- a/mypy/expandtype.py +++ b/mypy/expandtype.py @@ -541,7 +541,8 @@ 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" + if unpacked.type.fullname != "builtins.tuple": + 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(). From ad423fd587e23bf3fe6aed470561446ed71e0b9a Mon Sep 17 00:00:00 2001 From: "Kai (Kazuya Ito)" Date: Fri, 30 Jan 2026 05:35:56 +0900 Subject: [PATCH 02/16] Add test case for unpacking TypeAlias with TypeVarTuple --- test-data/unit/check-type-aliases.test | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test-data/unit/check-type-aliases.test b/test-data/unit/check-type-aliases.test index 61eda2bd7774..16615dae4526 100644 --- a/test-data/unit/check-type-aliases.test +++ b/test-data/unit/check-type-aliases.test @@ -1237,6 +1237,18 @@ Ta2 = TypeAliasType("Ta2", None, type_params=(Unpack[Ts],)) # E: Free type vari [builtins fixtures/tuple.pyi] +[case testGenericTypeAliasArgOfTypeAliasIsUnpackedTuple] +from typing_extensions import TypeAlias +from typing import TypeVarTuple, Unpack + +Ts = TypeVarTuple('Ts') + +TA: TypeAlias = tuple[Unpack[Ts]] + +v1: TA[*list[int]] # E: "list[int]" cannot be unpacked (must be tuple or TypeVarTuple) +v2: TA[Unpack[list[int]]] # E: "list[int]" cannot be unpacked (must be tuple or TypeVarTuple) +[builtins fixtures/tuple.pyi] + [case testAliasInstanceNameClash] from lib import func class A: ... From f92844f66e8263a57cbb2373edaa965dd7bdf2c4 Mon Sep 17 00:00:00 2001 From: "Kai (Kazuya Ito)" Date: Fri, 30 Jan 2026 06:26:29 +0900 Subject: [PATCH 03/16] Fix type alias unpacking syntax errors in tests Updated type alias test cases to reflect syntax changes. --- test-data/unit/check-type-aliases.test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test-data/unit/check-type-aliases.test b/test-data/unit/check-type-aliases.test index 16615dae4526..a1b6583662b6 100644 --- a/test-data/unit/check-type-aliases.test +++ b/test-data/unit/check-type-aliases.test @@ -1245,8 +1245,8 @@ Ts = TypeVarTuple('Ts') TA: TypeAlias = tuple[Unpack[Ts]] -v1: TA[*list[int]] # E: "list[int]" cannot be unpacked (must be tuple or TypeVarTuple) -v2: TA[Unpack[list[int]]] # E: "list[int]" cannot be unpacked (must be tuple or TypeVarTuple) +v1: TA[*list[int]] # E: Invalid syntax... +v2: TA[Unpack[list[int]]] # E: Invalid syntax... [builtins fixtures/tuple.pyi] [case testAliasInstanceNameClash] From bc3db3d265b188a074cb7950d87880074309d63e Mon Sep 17 00:00:00 2001 From: "Kai (Kazuya Ito)" Date: Fri, 30 Jan 2026 06:49:58 +0900 Subject: [PATCH 04/16] Improve error messages for type alias unpacking Update error messages for invalid syntax in type alias tests. --- test-data/unit/check-type-aliases.test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test-data/unit/check-type-aliases.test b/test-data/unit/check-type-aliases.test index a1b6583662b6..16615dae4526 100644 --- a/test-data/unit/check-type-aliases.test +++ b/test-data/unit/check-type-aliases.test @@ -1245,8 +1245,8 @@ Ts = TypeVarTuple('Ts') TA: TypeAlias = tuple[Unpack[Ts]] -v1: TA[*list[int]] # E: Invalid syntax... -v2: TA[Unpack[list[int]]] # E: Invalid syntax... +v1: TA[*list[int]] # E: "list[int]" cannot be unpacked (must be tuple or TypeVarTuple) +v2: TA[Unpack[list[int]]] # E: "list[int]" cannot be unpacked (must be tuple or TypeVarTuple) [builtins fixtures/tuple.pyi] [case testAliasInstanceNameClash] From d24ccff3e899ff653775312e6e70ac73df467943 Mon Sep 17 00:00:00 2001 From: "Kai (Kazuya Ito)" Date: Fri, 30 Jan 2026 07:41:51 +0900 Subject: [PATCH 05/16] Update check-type-aliases.test with new cases Add tests for type alias unpacking with lists. --- test-data/unit/check-type-aliases.test | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/test-data/unit/check-type-aliases.test b/test-data/unit/check-type-aliases.test index 16615dae4526..6c7b042548d0 100644 --- a/test-data/unit/check-type-aliases.test +++ b/test-data/unit/check-type-aliases.test @@ -1245,8 +1245,16 @@ Ts = TypeVarTuple('Ts') TA: TypeAlias = tuple[Unpack[Ts]] -v1: TA[*list[int]] # E: "list[int]" cannot be unpacked (must be tuple or TypeVarTuple) -v2: TA[Unpack[list[int]]] # E: "list[int]" cannot be unpacked (must be tuple or TypeVarTuple) +v1: TA[*list[int]] +v2: TA[Unpack[list[int]]] + +[out-python3.10] +main:8: error: Invalid syntax +main:9: error: Invalid syntax + +[out] +main:8: error: "list[int]" cannot be unpacked (must be tuple or TypeVarTuple) +main:9: error: "list[int]" cannot be unpacked (must be tuple or TypeVarTuple) [builtins fixtures/tuple.pyi] [case testAliasInstanceNameClash] From cb768f6dc0f9c9b3cb535954677f5e93808d8ad3 Mon Sep 17 00:00:00 2001 From: "Kai (Kazuya Ito)" Date: Fri, 30 Jan 2026 08:09:21 +0900 Subject: [PATCH 06/16] Fix unpacking errors in type alias tests Update type alias tests to reflect unpacking errors for list[int]. --- test-data/unit/check-type-aliases.test | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/test-data/unit/check-type-aliases.test b/test-data/unit/check-type-aliases.test index 6c7b042548d0..41b9e9b82092 100644 --- a/test-data/unit/check-type-aliases.test +++ b/test-data/unit/check-type-aliases.test @@ -1238,6 +1238,7 @@ Ta2 = TypeAliasType("Ta2", None, type_params=(Unpack[Ts],)) # E: Free type vari [builtins fixtures/tuple.pyi] [case testGenericTypeAliasArgOfTypeAliasIsUnpackedTuple] +# flags: --python-version 3.10 from typing_extensions import TypeAlias from typing import TypeVarTuple, Unpack @@ -1245,17 +1246,11 @@ Ts = TypeVarTuple('Ts') TA: TypeAlias = tuple[Unpack[Ts]] -v1: TA[*list[int]] -v2: TA[Unpack[list[int]]] - -[out-python3.10] -main:8: error: Invalid syntax -main:9: error: Invalid syntax +v1: TA[*list[int]] # E: "list[int]" cannot be unpacked (must be tuple or TypeVarTuple) +v2: TA[Unpack[list[int]]] # E: "list[int]" cannot be unpacked (must be tuple or TypeVarTuple) -[out] -main:8: error: "list[int]" cannot be unpacked (must be tuple or TypeVarTuple) -main:9: error: "list[int]" cannot be unpacked (must be tuple or TypeVarTuple) [builtins fixtures/tuple.pyi] +xfail: True [case testAliasInstanceNameClash] from lib import func From d7b46154e6db209c6f23b35cf665061e5749ef84 Mon Sep 17 00:00:00 2001 From: "Kai (Kazuya Ito)" Date: Fri, 30 Jan 2026 08:31:32 +0900 Subject: [PATCH 07/16] Remove Python version flag from test case --- test-data/unit/check-type-aliases.test | 1 - 1 file changed, 1 deletion(-) diff --git a/test-data/unit/check-type-aliases.test b/test-data/unit/check-type-aliases.test index 41b9e9b82092..02129c01ce1d 100644 --- a/test-data/unit/check-type-aliases.test +++ b/test-data/unit/check-type-aliases.test @@ -1238,7 +1238,6 @@ Ta2 = TypeAliasType("Ta2", None, type_params=(Unpack[Ts],)) # E: Free type vari [builtins fixtures/tuple.pyi] [case testGenericTypeAliasArgOfTypeAliasIsUnpackedTuple] -# flags: --python-version 3.10 from typing_extensions import TypeAlias from typing import TypeVarTuple, Unpack From 1221422c961e9c24dd9d4c95c91c47982adf2188 Mon Sep 17 00:00:00 2001 From: "Kai (Kazuya Ito)" Date: Fri, 30 Jan 2026 08:56:23 +0900 Subject: [PATCH 08/16] Rename test case for unpacked tuple to xfail --- test-data/unit/check-type-aliases.test | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test-data/unit/check-type-aliases.test b/test-data/unit/check-type-aliases.test index 02129c01ce1d..d757632e06df 100644 --- a/test-data/unit/check-type-aliases.test +++ b/test-data/unit/check-type-aliases.test @@ -1237,7 +1237,7 @@ Ta2 = TypeAliasType("Ta2", None, type_params=(Unpack[Ts],)) # E: Free type vari [builtins fixtures/tuple.pyi] -[case testGenericTypeAliasArgOfTypeAliasIsUnpackedTuple] +[case testGenericTypeAliasArgOfTypeAliasIsUnpackedTuple-xfail] from typing_extensions import TypeAlias from typing import TypeVarTuple, Unpack @@ -1245,11 +1245,10 @@ Ts = TypeVarTuple('Ts') TA: TypeAlias = tuple[Unpack[Ts]] +# For Python 3.10, error: Invalid syntax v1: TA[*list[int]] # E: "list[int]" cannot be unpacked (must be tuple or TypeVarTuple) v2: TA[Unpack[list[int]]] # E: "list[int]" cannot be unpacked (must be tuple or TypeVarTuple) - [builtins fixtures/tuple.pyi] -xfail: True [case testAliasInstanceNameClash] from lib import func From 0c0d5821d85d335bd288a3440fcff16ef0f7378a Mon Sep 17 00:00:00 2001 From: "Kai (Kazuya Ito)" Date: Fri, 30 Jan 2026 08:58:08 +0900 Subject: [PATCH 09/16] Clarify unpacked type handling in expandtype.py Add comment to clarify behavior during semantic analysis. --- mypy/expandtype.py | 1 + 1 file changed, 1 insertion(+) diff --git a/mypy/expandtype.py b/mypy/expandtype.py index 81dafc1a6b58..5790b717172a 100644 --- a/mypy/expandtype.py +++ b/mypy/expandtype.py @@ -541,6 +541,7 @@ def visit_tuple_type(self, t: TupleType) -> Type: if isinstance(item, UnpackType): unpacked = get_proper_type(item.type) if isinstance(unpacked, Instance): + # expand_type() may be called during semantic analysis, before invalid unpacks are fixed. if unpacked.type.fullname != "builtins.tuple": return t.partial_fallback.accept(self) if t.partial_fallback.type.fullname != "builtins.tuple": From 2676b2488f04a5f5b307ed9c5dd689898eca3831 Mon Sep 17 00:00:00 2001 From: "Kai (Kazuya Ito)" Date: Fri, 30 Jan 2026 09:19:24 +0900 Subject: [PATCH 10/16] Fix unpacking errors in TypeAlias tests Updated test cases for TypeAlias unpacking in Python. --- test-data/unit/check-type-aliases.test | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test-data/unit/check-type-aliases.test b/test-data/unit/check-type-aliases.test index d757632e06df..fe0fef3060a0 100644 --- a/test-data/unit/check-type-aliases.test +++ b/test-data/unit/check-type-aliases.test @@ -1246,8 +1246,9 @@ Ts = TypeVarTuple('Ts') TA: TypeAlias = tuple[Unpack[Ts]] # For Python 3.10, error: Invalid syntax -v1: TA[*list[int]] # E: "list[int]" cannot be unpacked (must be tuple or TypeVarTuple) -v2: TA[Unpack[list[int]]] # E: "list[int]" cannot be unpacked (must be tuple or TypeVarTuple) +# 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 112192547ba18200d07612f3e41ee916a5e409a3 Mon Sep 17 00:00:00 2001 From: "Kai (Kazuya Ito)" Date: Fri, 30 Jan 2026 14:46:10 +0900 Subject: [PATCH 11/16] Refactor test case for generic type alias unpacking Removed xfail marker from test case and updated comments for clarity. --- test-data/unit/check-type-aliases.test | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/test-data/unit/check-type-aliases.test b/test-data/unit/check-type-aliases.test index fe0fef3060a0..208333f4fcc1 100644 --- a/test-data/unit/check-type-aliases.test +++ b/test-data/unit/check-type-aliases.test @@ -1237,7 +1237,7 @@ Ta2 = TypeAliasType("Ta2", None, type_params=(Unpack[Ts],)) # E: Free type vari [builtins fixtures/tuple.pyi] -[case testGenericTypeAliasArgOfTypeAliasIsUnpackedTuple-xfail] +[case testGenericTypeAliasArgOfTypeAliasIsUnpackedTuple] from typing_extensions import TypeAlias from typing import TypeVarTuple, Unpack @@ -1245,10 +1245,9 @@ 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]]] +v1: TA[*list[int]] # E: "list[int]" cannot be unpacked (must be tuple or TypeVarTuple) +v2: TA[Unpack[list[int]]] # E: "list[int]" cannot be unpacked (must be tuple or TypeVarTuple) +# python3.10: Invalid syntax [builtins fixtures/tuple.pyi] [case testAliasInstanceNameClash] From 40cd52d33ff61534cf125fac97ad7c636525e3db Mon Sep 17 00:00:00 2001 From: "Kai (Kazuya Ito)" Date: Fri, 30 Jan 2026 15:14:56 +0900 Subject: [PATCH 12/16] Update tests for unpacked type alias syntax Add test cases for unpacked type aliases in Python 3.10 and 3.11 --- test-data/unit/check-type-aliases.test | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/test-data/unit/check-type-aliases.test b/test-data/unit/check-type-aliases.test index 208333f4fcc1..9df4a7650693 100644 --- a/test-data/unit/check-type-aliases.test +++ b/test-data/unit/check-type-aliases.test @@ -1237,17 +1237,26 @@ Ta2 = TypeAliasType("Ta2", None, type_params=(Unpack[Ts],)) # E: Free type vari [builtins fixtures/tuple.pyi] -[case testGenericTypeAliasArgOfTypeAliasIsUnpackedTuple] +[case testGenericTypeAliasArgOfTypeAliasIsUnpackedTuple-python311] from typing_extensions import TypeAlias from typing import TypeVarTuple, Unpack Ts = TypeVarTuple('Ts') - TA: TypeAlias = tuple[Unpack[Ts]] v1: TA[*list[int]] # E: "list[int]" cannot be unpacked (must be tuple or TypeVarTuple) v2: TA[Unpack[list[int]]] # E: "list[int]" cannot be unpacked (must be tuple or TypeVarTuple) -# python3.10: Invalid syntax +[builtins fixtures/tuple.pyi] + +[case testGenericTypeAliasArgOfTypeAliasIsUnpackedTuple-python310] +from typing_extensions import TypeAlias +from typing import TypeVarTuple, Unpack + +Ts = TypeVarTuple('Ts') +TA: TypeAlias = tuple[Unpack[Ts]] + +v1: TA[*list[int]] # E: main:7: error: Invalid syntax +v2: TA[Unpack[list[int]]] # E: main:8: error: Invalid syntax [builtins fixtures/tuple.pyi] [case testAliasInstanceNameClash] From c4fc5e560ec78fa20683edf710aa7334612b95ec Mon Sep 17 00:00:00 2001 From: "Kai (Kazuya Ito)" Date: Fri, 30 Jan 2026 15:32:30 +0900 Subject: [PATCH 13/16] Rename test cases for unpacked tuple compatibility --- test-data/unit/check-type-aliases.test | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test-data/unit/check-type-aliases.test b/test-data/unit/check-type-aliases.test index 9df4a7650693..b24656d14952 100644 --- a/test-data/unit/check-type-aliases.test +++ b/test-data/unit/check-type-aliases.test @@ -1237,7 +1237,8 @@ Ta2 = TypeAliasType("Ta2", None, type_params=(Unpack[Ts],)) # E: Free type vari [builtins fixtures/tuple.pyi] -[case testGenericTypeAliasArgOfTypeAliasIsUnpackedTuple-python311] +[case testGenericTypeAliasArgOfTypeAliasIsUnpackedTuple] +# flags: --python-version 3.11 from typing_extensions import TypeAlias from typing import TypeVarTuple, Unpack @@ -1248,7 +1249,8 @@ v1: TA[*list[int]] # E: "list[int]" cannot be unpacked (must be tuple or v2: TA[Unpack[list[int]]] # E: "list[int]" cannot be unpacked (must be tuple or TypeVarTuple) [builtins fixtures/tuple.pyi] -[case testGenericTypeAliasArgOfTypeAliasIsUnpackedTuple-python310] +[case testGenericTypeAliasArgOfTypeAliasIsUnpackedTuple310] +# flags: --python-version 3.10 from typing_extensions import TypeAlias from typing import TypeVarTuple, Unpack From 5999e316fc98e62be83bf381d12b1b7e2defa370 Mon Sep 17 00:00:00 2001 From: "Kai (Kazuya Ito)" Date: Fri, 30 Jan 2026 15:52:56 +0900 Subject: [PATCH 14/16] Refine error messages in check-type-aliases test Update error messages for type alias unpacking tests. --- test-data/unit/check-type-aliases.test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test-data/unit/check-type-aliases.test b/test-data/unit/check-type-aliases.test index b24656d14952..ee7afddd0796 100644 --- a/test-data/unit/check-type-aliases.test +++ b/test-data/unit/check-type-aliases.test @@ -1257,8 +1257,8 @@ from typing import TypeVarTuple, Unpack Ts = TypeVarTuple('Ts') TA: TypeAlias = tuple[Unpack[Ts]] -v1: TA[*list[int]] # E: main:7: error: Invalid syntax -v2: TA[Unpack[list[int]]] # E: main:8: error: Invalid syntax +v1: TA[*list[int]] # E: "list[int]" cannot be unpacked (must be tuple or TypeVarTuple) +v2: TA[Unpack[list[int]]] # E: "list[int]" cannot be unpacked (must be tuple or TypeVarTuple) [builtins fixtures/tuple.pyi] [case testAliasInstanceNameClash] From 8a3c1d0d175f79229a2018bcaa06c14c93d944dc Mon Sep 17 00:00:00 2001 From: "Kai (Kazuya Ito)" Date: Fri, 30 Jan 2026 16:15:29 +0900 Subject: [PATCH 15/16] Revise error messages in check-type-aliases tests Update error messages for unpacking list in type alias tests to reflect Python version requirements. --- test-data/unit/check-type-aliases.test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test-data/unit/check-type-aliases.test b/test-data/unit/check-type-aliases.test index ee7afddd0796..f009728f742a 100644 --- a/test-data/unit/check-type-aliases.test +++ b/test-data/unit/check-type-aliases.test @@ -1245,7 +1245,7 @@ from typing import TypeVarTuple, Unpack Ts = TypeVarTuple('Ts') TA: TypeAlias = tuple[Unpack[Ts]] -v1: TA[*list[int]] # E: "list[int]" cannot be unpacked (must be tuple or TypeVarTuple) +v1: TA[*list[int]] # E: Invalid syntax; you likely need to run mypy using Python 3.11 or newer v2: TA[Unpack[list[int]]] # E: "list[int]" cannot be unpacked (must be tuple or TypeVarTuple) [builtins fixtures/tuple.pyi] @@ -1257,7 +1257,7 @@ from typing import TypeVarTuple, Unpack Ts = TypeVarTuple('Ts') TA: TypeAlias = tuple[Unpack[Ts]] -v1: TA[*list[int]] # E: "list[int]" cannot be unpacked (must be tuple or TypeVarTuple) +v1: TA[*list[int]] # E: Invalid syntax v2: TA[Unpack[list[int]]] # E: "list[int]" cannot be unpacked (must be tuple or TypeVarTuple) [builtins fixtures/tuple.pyi] From 740cdb1417b9b07a314c131e5b886e6c463fadcb Mon Sep 17 00:00:00 2001 From: "Kai (Kazuya Ito)" Date: Fri, 30 Jan 2026 16:31:03 +0900 Subject: [PATCH 16/16] Fix error messages in check-type-aliases test Updated error messages for unpacking list[int] in type alias tests. --- test-data/unit/check-type-aliases.test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test-data/unit/check-type-aliases.test b/test-data/unit/check-type-aliases.test index f009728f742a..ee7afddd0796 100644 --- a/test-data/unit/check-type-aliases.test +++ b/test-data/unit/check-type-aliases.test @@ -1245,7 +1245,7 @@ from typing import TypeVarTuple, Unpack Ts = TypeVarTuple('Ts') TA: TypeAlias = tuple[Unpack[Ts]] -v1: TA[*list[int]] # E: Invalid syntax; you likely need to run mypy using Python 3.11 or newer +v1: TA[*list[int]] # E: "list[int]" cannot be unpacked (must be tuple or TypeVarTuple) v2: TA[Unpack[list[int]]] # E: "list[int]" cannot be unpacked (must be tuple or TypeVarTuple) [builtins fixtures/tuple.pyi] @@ -1257,7 +1257,7 @@ from typing import TypeVarTuple, Unpack Ts = TypeVarTuple('Ts') TA: TypeAlias = tuple[Unpack[Ts]] -v1: TA[*list[int]] # E: Invalid syntax +v1: TA[*list[int]] # E: "list[int]" cannot be unpacked (must be tuple or TypeVarTuple) v2: TA[Unpack[list[int]]] # E: "list[int]" cannot be unpacked (must be tuple or TypeVarTuple) [builtins fixtures/tuple.pyi]