How can one extend __class_getitem__
for a Python Generic
class? I want to add arguments to __class_getitem__
while having some be propagated upwards to Generic.__class_getitem__
.
Please see the below code snippet for an example use case (that doesn't run):
from typing import ClassVar, Generic, TypeVar
T = TypeVar("T")
class Foo(Generic[T]):
cls_attr: ClassVar[int]
def __class_getitem__(cls, cls_attr: int, item):
cls.cls_attr = cls_attr
return super().__class_getitem__(item)
def __init__(self, arg: T):
pass
foo = Foo[1, bool](arg=True)
Gives me this TypeError
:
Traceback (most recent call last):
File "/path/to/file.py", line 17, in <module>
foo = Foo[1, bool](arg=True)
TypeError: Foo.__class_getitem__() missing 1 required positional argument: 'item'
CodePudding user response:
If you're looking to have two generic vars then you can do that like this:
from typing import Generic, TypeVar
T = TypeVar("T")
V = TypeVar("V")
class Foo(Generic[T, V]):
def __init__(self, arg: T):
pass
foo: Foo[int, bool] = Foo(arg=True)
CodePudding user response:
As @juanpa.arrivillaga suggests, this is the way to go:
from typing import ClassVar, Generic, TypeVar
T = TypeVar("T")
class Foo(Generic[T]):
cls_attr: ClassVar[int]
def __class_getitem__(cls, item: tuple[int, T]):
cls.cls_attr = item[0]
return super().__class_getitem__(item[1])
def __init__(self, arg: T):
self.arg = arg
foo = Foo[1, bool](arg=True)
assert foo.cls_attr == 1
assert foo.arg
Unfortunately, it looks like Python type inspection tooling is not advanced enough to understand this pattern. For example, mypy==0.971
(Sept 2022) doesn't support __class_getitem__
yet per https://github.com/python/mypy/issues/11501.