Is there any way to type an abstract parent class method such that the child class method is known to return itself, instead of the abstract parent.
class Parent(ABC):
@abstractmethod
def method(self) -> [what to hint here]:
pass
class Child1(Parent)
def method(self):
pass
def other_method(self):
pass
class GrandChild1(Child1)
def other_method_2(self):
pass
This is more to improve autocompletes for IDEs like PyCharm or VScode's python plugin.
So, the general approach is described in the docs here
import typing
from abc import ABC, abstractmethod
T = typing.TypeVar('T', bound='Parent') # use string
class Parent(ABC):
@abstractmethod
def method(self: T) -> T:
...
class Child1(Parent):
def method(self: T) -> T:
return self
def other_method(self):
pass
class GrandChild1(Child1):
def other_method_2(self):
pass
reveal_type(Child1().method())
reveal_type(GrandChild1().method())
And mypy
gives us:
test_typing.py:22: note: Revealed type is 'test_typing.Child1*'
test_typing.py:23: note: Revealed type is 'test_typing.GrandChild1*'
Note, I had to keep using type-variables to get this to work, so when I originally tried to use the actual child class in the child class annotation, it (erroneously?) inherited the type in the grandchild:
class Child1(Parent):
def method(self) -> Child1:
return self
I'd get with mypy:
test_typing.py:22: note: Revealed type is 'test_typing.Child1'
test_typing.py:23: note: Revealed type is 'test_typing.Child1'
Again, I am not sure if this is expected/correct behavior. The mypy documentation currently has a warning:
This feature is experimental. Checking code with type annotations for self arguments is still not fully implemented. Mypy may disallow valid code or allow unsafe code.