Typing on child class' methods of a Generic base class

Dieter Maurer dieter at handshake.de
Sat Mar 12 13:24:59 EST 2022


Nicolas Haller wrote at 2022-3-12 12:05 -0500:
>On 2022-03-10 12:31, Dieter Maurer wrote:
>> Nicolas Haller wrote at 2022-3-9 10:53 -0500:
>>> ...
>>> The documentation about "user-defined generic types"[1] says that I can
>>> fix some types on a child class (class MyDict(Mapping[str, T]):) but
>>> doesn't say much about the signature of the methods I need to
>>> implement/override on that child class.
>>
>> I have the fealing that this is a case of (generic type) "specialization".
>> In this setup, `Mapping` would be a generic type with two type
>> variables `K` (the key type) and `V` (the value type).
>> The signatures of its methods would use those type variables.
>> In your example, you specialize the key type to `str` (and
>> leave the value type generic). The signatures of the methods
>> would automatically follow this specialization -- without the need
>> to do anything.
>
>If I understand correctly, you're saying I should use the first
>alternative by keeping the signature as it is in the base class:
>---
>T = TypeVar("T")
>
>
>class Base(Generic[T], metaclass=ABCMeta):
>     """A base class."""
>
>     @abstractmethod
>     def _private_method(self, an_arg: T) -> T:
>         ...
>
>     def public_method(self, an_arg: T) -> T:
>         from_private_method = self._private_method(an_arg)
>         return from_private_method
>
>class Alternative1(Base[int]):
>     def _private_method(self, an_arg: T) -> T:  # I keep T
>         return 42
>---
>
>The problem with it is that mypy doesn´t seem quite happy with it:
>./scratch.py:22: error: Incompatible return value type (got "int",
>expected "T")
>
>Do you think this is error is incorrect?

No, I do not think so.

The `Base[int]` means that the generic type variable `T` was
specialized to `int`. This means that in this context
`_private_method` returns `int` (not a generic `T`).

You either do not type annotate the overriding methods
or you use the specialization (if any).


More information about the Python-list mailing list