Note that a ClassVar parameter cannot include any type variables, regardless of the level of nesting: ClassVar[T] and ClassVar[List[Set[T]]] are both invalid if T is a type variable.
I’m curious why this restriction exists. It’s not stated in the PEP itself; perhaps it’s somewhere in the annals of the Typing github…
This question arose while I was trying to write and type a generic base class that has two members where one is an instance variable holding an instance of some type and the other is a class variable holding the type itself:
class _ApiClientBase[C: (httpx.Client, httpx.AsyncClient), Auth: httpx.Auth](ABC):
base_url: str
client: C
_auth: Auth
_auth_cls: ClassVar[Type] # I wanted ClassVar[Type[Auth]]
@property
def auth(self) -> Auth:
return self._auth
@auth.setter
@abstractmethod
def auth(self, value: Any):
if not isinstance(value, self._auth_cls):
self._auth = self._auth_cls(value)
else:
self._auth = value
The restriction on ClassVar means I must give up either marking the attribute as a class variable, or I must give up marking its relationship to the type of _auth.
This is a rough draft design that certainly will not survive revision. Suggestions are welcome, but my question here is about ClassVar.
A ClassVar occurs once per class, not once for each generic parametrization.
To give a (different) example, suppose we implement a generic linked list.
The linked list of ints shares its .head with the linked list of strs. There’s only one.
That seems to me there’s no point in using a TypeVar in a ClassVar.
My goal was for implementations of the ABC to override the ClassVar with a more specific type, and declaring it in the ABC was essentially just documentation since the ABC itself would never have a value for that attribute.
I was also getting the run-around because authlib is using httpx2 while my codebase was using httpx, where the names are all the same but the types are technically different. Updating that let me directly use the base class I was trying to parameterize over in the ClassVar declaration.