I have a superclass that has a method which is shared by its subclasses. However, this method should return an object with a type that is defined on the subclass. I'd like the return type for the method to be statically annotated (not a dynamic type) so code using the subclasses can benefit from mypy
type checking on the return values. But I don't want to have to redefine the common method on the subclass just to provide its type annotation. Is this possible with python type annotations and mypy?
Something like this:
from typing import Type
class AbstractModel:
pass
class OrderModel(AbstractModel):
def do_order_stuff():
pass
class AbstractRepository:
model: Type[AbstractModel]
def get(self) -> model:
return self.model()
class OrderRepository(AbstractRepository):
model = OrderModel
repo = OrderRepository()
order = repo.get()
# Type checkers (like mypy) should recognize that this is valid
order.do_order_stuff()
# Type checkers should complain about this; because `OrderModel`
# does not define `foo`
order.foo()
The tricky move here is that get()
is defined on the superclass AbstractRepository
, which doesn't yet know the type of model
. (And the -> model
annotation fails, since the value of model
hasn't been specified yet).
The value of model
is specified by the subclass, but the subclass doesn't (re)define get()
in order to provide the annotation. It seems like this should be statically analyzable; though it's a little tricky, since it would require the static analyzer to trace the model
reference from the superclass to the subclass.
Any way to accomplish both a shared superclass implementation and a precise subclass return type?
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…