Reputation: 672
Consider the following:
from __future__ import annotations
class A:
def __init__(self):
print("A")
self.hello = "hello"
# how do I type this so that the return type is A for A.bobo()
# and B for B.bobo()?
@classmethod
def bobo(cls) -> UnknownType:
return cls()
class B(A):
def __init__(self):
print("B")
super().__init__()
self.world = "world"
instance_of_B = B.bobo() # prints "B", then "A", and returns an instance of B
I want to type-hint the bobo
class method, so that mypy can know that in the case of B
's bobo
method, it's not just an instance of A
that's returned, but actually an instance of B
. I'm really unclear on how to do that, or if it's even possible. I thought that something like Type[cls]
might do the trick, but I'm not sure if that even makes syntactic sense to mypy.
Upvotes: 14
Views: 11322
Reputation: 3083
For an example of how to apply Brian's answer:
TypeVar
:from typing import TypeVar
AnyA = TypeVar("AnyA", bound="A")
class A:
def __init__(self):
print("A")
self.hello = "hello"
@classmethod
def bobo(cls: type[AnyA]) -> AnyA:
return cls()
class B(A):
def __init__(self):
print("B")
super().__init__()
self.world = "world"
reveal_type(B.bobo()) # B
Self
:from typing import Self
class A:
def __init__(self):
print("A")
self.hello = "hello"
@classmethod
def bobo(cls) -> Self:
return cls()
class B(A):
def __init__(self):
print("B")
super().__init__()
self.world = "world"
reveal_type(B.bobo()) # B
If your version of Python doesn't have Self
yet, you can use the typing-extensions package, which serves as backport for some typing features:
- from typing import Self
+ from typing_extensions import Self
Upvotes: 27