Use a TypeVar
to parameterise over the type of self
. This is always an instance of "the current class", allowing to use the TypeVar
to express the type respecting inheritance:
from typing import TypeVar
Self = TypeVar('Self')
class A:
# `bar` must be of the same type as `self`
def foo(self: Self, bar: Self):
...
class B(A):
...
When calling A().foo
or B().foo
, Self
is automatically inferred to the concrete class A
or B
, respectively. This then automatically constraints the other parameter to match the inferred TypeVar
and thus the class.
The same mechanism can be used for @classmethod
s as well. Instead of self: Self
to capture the type of the instance, use cls: Type[Self]
to capture the type directly.
from typing import TypeVar, Type
Self = TypeVar('Self')
class A:
# `bar` must be an instance of `cls`
@classmethod
def foo(cls: Type[Self], bar: Self):
...
class B(A):
...