Cristian S. Rocha
Cristian S. Rocha

Reputation: 113

How to specify an instance with a subclass without typing hint errors?

I'm using instance __class__ attribute to specify an instance created from the super class. But MyPy rejects it with Incompatible return value type.

Is there a most pythonic option to do that without ignoring it?

Here is my example code:

class A:
    def __init__(self, a: int = None):
        self.a = a or 1


class B(A):
    def b(self) -> int:
        return 5 + self.a

    @classmethod
    def specify(cls, a_instance: A) -> 'B':
        a_instance.__class__ = cls
        return a_instance  # type: ignore


if __name__ == "__main__":
    s = A(6)
    s = B.specify(s)
    print(s.b())

and the error if you don't ignore typing:

 % mypy scratch_7.py
scratch_7.py:13: error: Incompatible return value type (got "A", expected "B")
Found 1 error in 1 file (checked 1 source file)

Upvotes: 1

Views: 63

Answers (1)

Taku
Taku

Reputation: 33744

mypy supports dynamically type casting with the use of typing.cast.

from typing import cast

class B(A):
    def b(self) -> int:
        return 5 + self.a

    @classmethod
    def specify(cls, a_instance: A) -> 'B':
        a_instance.__class__ = cls
        a_instance = cast('B', a_instance)
        return a_instance

# Success: no issues found in 1 source file

typing.cast doesn't change the value, it only signals the type checker (mypy) that the type has changed.

Upvotes: 1

Related Questions