2

Similar but different to How do I type hint a method with the type of the enclosing class?.

How can I set something on the parent class so that a type hint gets updated through inheritance?

class A:
    # Make some change here
    def foo(self, bar: 'A'):
        pass


class B(A):
    # Get the hinting of the code below, but without writing it for every inheritor.
    # def foo(self, bar: 'B'):
    #     pass
    pass
Alex Waygood
  • 6,304
  • 3
  • 24
  • 46
Jungroth
  • 392
  • 2
  • 8

1 Answers1

0

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 @classmethods 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):
    ...
MisterMiyagi
  • 44,374
  • 10
  • 104
  • 119