Consider:
from __future__ import annotations
class A:
@classmethod
def get(cls) -> A:
return cls()
class B(A):
pass
def func() -> B: # Line 12
return B.get()
Running mypy on this we get:
$ mypy test.py
test.py:12: error: Incompatible return value type (got "A", expected "B")
Found 1 error in 1 file (checked 1 source file)
Additionally, I have checked to see if old-style recursive annotations work. That is:
# from __future__ import annotations
class A:
@classmethod
def get(cls) -> "A":
# ...
...to no avail.
Of course one could do:
from typing import cast
def func() -> B: # Line 12
return cast(B, B.get())
Every time this case pops up. But I would like to avoid doing that.
How should one go about typing this?
A, you need to cast it explicitely. If you just want to type-annotate your function correctly, why notdef func() -> A?Binfunc. For example, suppose we have classes representing database entities. We have a common classEntityand subclasses likeUserandProject. These subclasses also have additional, idiosyncratic attributes that matter. We want to be explicit about whether your returning aUserorProjectbecause that will constrain what we can do downstream.