From 7f3503c90d1e154d219de08aa866d5ef436ff0e1 Mon Sep 17 00:00:00 2001 From: say-apm Date: Tue, 12 May 2026 11:39:28 -0700 Subject: [PATCH] Fix crash on Unpack used without arguments in class bases analyze_unbound_tvar accessed t.args[0] unconditionally when the base was Unpack with no arguments (e.g. Protocol[Unpack]), raising IndexError. Return None in that case so a proper 'Free type variable expected' error is reported instead. Fixes #21467 --- mypy/semanal.py | 3 +++ test-data/unit/check-typevar-tuple.test | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/mypy/semanal.py b/mypy/semanal.py index fb6f299a37956..da58c95869667 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -2403,6 +2403,9 @@ def analyze_unbound_tvar(self, t: Type) -> tuple[str, TypeVarLikeExpr] | None: if isinstance(t, UnboundType): sym = self.lookup_qualified(t.name, t) if sym and sym.fullname in UNPACK_TYPE_NAMES: + if not t.args: + # Unpack used without arguments, e.g. `Protocol[Unpack]` + return None inner_t = t.args[0] if isinstance(inner_t, UnboundType): return self.analyze_unbound_tvar_impl(inner_t, is_unpacked=True) diff --git a/test-data/unit/check-typevar-tuple.test b/test-data/unit/check-typevar-tuple.test index 7ca21b280aad0..ff5cdc8719bc6 100644 --- a/test-data/unit/check-typevar-tuple.test +++ b/test-data/unit/check-typevar-tuple.test @@ -2765,3 +2765,11 @@ def func(d: Callable[[Unpack[Ts]], T]) -> T: ... y = func[1, int] # E: Type application is only supported for generic classes \ # E: Invalid type: try using Literal[1] instead? [builtins fixtures/tuple.pyi] + +[case testTypeVarTupleUnpackWithoutArgsInProtocol] +# https://github.com/python/mypy/issues/21467 +from typing import Protocol, Unpack + +class C(Protocol[Unpack]): # E: Free type variable expected in Protocol[...] + pass +[builtins fixtures/tuple.pyi]