typing icon indicating copy to clipboard operation
typing copied to clipboard

Spec: More precision on type parameter order

Open JelleZijlstra opened this issue 5 months ago • 0 comments

The spec currently isn't very precise on the order in which type parameters appear in a class. (Given a class C that is generic over type parameters T1 and T2, does C[int, str] mean that T1 is bound to int or that T2 is bound to int?)

I think the rule should be:

  • If PEP 695 syntax is used, the order is the order in which the type parameters appear in the type parameter list.
  • If the class has Generic[...] as a syntactic base, the order is the order of the type arguments to Generic.
  • If the class has Protocol[...] as a syntactic base, the order is the order of the type arguments to Protocol. This applies only if Protocol is subscripted, not if the class inherits from bare Protocol.
  • Otherwise, the order is the order in which the type parameters appear syntactically in the base class list.

As far as I know, this is how all type checkers currently behave, but we just found out it's not how the runtime behaves when Protocol is involved: https://github.com/python/cpython/issues/137191#issuecomment-3132748382.

In these examples, all classes are generic over two parameters T1 and T2, and in all cases the type parameter order is T1, T2:

from typing import Generic, Protocol, TypeVar

class C1[T1, T2]: ...  # order is T1, T2

T1 = TypeVar("T1")
T2 = TypeVar("T2")

class C2(C1[T2, T1], Generic[T1, T2]): ...  # order is T1, T2

class GenericProto[T1, T2](Protocol):  ...  # order is T1, T2

class Proto2(GenericProto[T2, T1], Protocol[T1, T2]): ...  # order is T1, T2

class Proto3(GenericProto[T1, T2], Protocol): ...  # order is T1, T2

class C3(C2[T1, T2]): ...  # order is T1, T2

We should change the spec to make this rule explicit. The only current rule appears to be in https://typing.python.org/en/latest/spec/generics.html#arbitrary-generic-types-as-base-classes "Type variables are applied to the defined class in the order in which they first appear in any generic base classes".

JelleZijlstra avatar Jul 29 '25 14:07 JelleZijlstra