wrufesh
wrufesh

Reputation: 1406

Python typing: best way to annotate parent class return subclass type object

I have a BaseClass like follow:

class BaseClass:
    @classmethod
    def create(cls, arg1: str) -> BaseClass:
        instance = cls(arg1)
        return instance

And a derived class like this:

class DerivedClass(BaseClass):
    def __init__(self, arg: str) -> None:
        self.arg = arg 

Now when I do

data: DerivedClass = DerivedClass.create('first arg)

mypy gives following error:

"BaseClass" cannot be assigned to declared type "DerivedClass"
"BaseClass" is incompatible with "DerivedClass"

How I solve it is by using typing.cast

data: DerivedClass = cast(
    DerivedClass, 
    DerivedClass.get(derived_class_instance)
)

How should i solve it without using typing.cast

Upvotes: 8

Views: 2240

Answers (1)

Mario Ishac
Mario Ishac

Reputation: 5877

You can change BaseClass to this:

T = TypeVar("T")

from typing import TypeVar, Type

class BaseClass:
    @classmethod
    def get(cls: Type[T], instance: T) -> T:
        return instance

This forces instance to be of the type that the get class method is being called on. So BaseClass.get takes a BaseClass and returns a BaseClass, while DerivedClass.get takes a DerivedClass and returns a DerivedClass. Running mypy results in:

Success: no issues found in 1 source file

Upvotes: 7

Related Questions