You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
PEP 695: type parameter bound referencing an earlier type parameter in the same list fails with "Name ... is not defined" #21922
Bug Report
PEP 695 explicitly allows a type parameter's bound to reference an earlier type parameter declared in the same type parameter list ("Type Parameter Scopes" section: "Type parameters are visible to other type parameters declared elsewhere in the list", with the only restriction being that an earlier parameter cannot reference a later one). Mypy rejects this with a name-defined error, both for classes and for functions, and for both the new PEP 695 bracket syntax and the classic TypeVar syntax.
To Reproduce
Minimal reproduction (class):
class Container[T]:
pass
class Foo[T, S: Container[T]]:
x: S
Minimal reproduction (function, same failure):
class Container[T]:
pass
def foo[T, S: Container[T]](x: S) -> None:
pass
Both are plain generic classes, not Protocol — the failure is not specific to protocols; the exact same error occurs when Container is a Protocol.
Expected Behavior
Both snippets should type-check cleanly. T is declared before S in the same type parameter list, and S's bound (Container[T]) only refers back to an earlier parameter, which PEP 695 explicitly permits.
For context, a bound with no parameters of its own works exactly as expected:
get_length("ok") # accepted
get_length(42) # error: Value of type variable "T" of "get_length" cannot be "int"
The failure only appears once the bound itself needs a type parameter (Container[T]), and that parameter must come from a sibling in the same list.
Actual Behavior
error: Name "T" is not defined [name-defined]
Your Environment
Mypy version: 2.1.0 (reproduced) and 2.3.1, the latest released version as of this report (also reproduced, installed in isolation)
Python version used: 3.13.12
Operating system: Linux
Additional context
Closely related to #20190 / #20021 (a PEP 696 default value referencing a sibling, fixed by #20021) — but that fix doesn't cover this: re-tested on 2.3.1 (which already includes it), still fails identically. #20190 is about a default value (Y=X), this one is about a bound (Y: Bound[X]) — likely the same underlying scope-resolution issue, but seemingly not fixed by the same change.
Additional information:
I asked claude to help me in the redaction of this ticket, but this is a real problem i meet in the real world, and i am very surprised this bug has not been repported yet.
Activity
A5rocks commentedon Sep 5, 2026
PEP 695: