I have a base class with a type hint of float
on a method's return.
In the child class, without redefining the signature, can I somehow update the type hint on the method's return to be int
?
Sample Code
#!/usr/bin/env python3.6
class SomeClass:
"""This class's some_method will return float."""
RET_TYPE = float
def some_method(self, some_input: str) -> float:
return self.RET_TYPE(some_input)
class SomeChildClass(SomeClass):
"""This class's some_method will return int."""
RET_TYPE = int
if __name__ == "__main__":
ret: int = SomeChildClass().some_method("42"). #
ret2: float = SomeChildClass().some_method("42")
My IDE complains about a type mismatch:
This is happening because my IDE is still using the type hint from SomeClass.some_method
.
Research
I think the solution might be to use generics, but I am not sure if there's a simpler way.
Python: how to override type hint on an instance attribute in a subclass?
Suggests maybe using instance variable annotations, but I am not sure how to do that for a return type.
Okay so I was able to play around and combine the answers from @AntonPomieshcheko and @KevinLanguasco to come up with the a solution where:
mypy
reports if a there's a mismatch of typesThis is exactly the behavior I had wanted. Thank you so much to everyone :)
#!/usr/bin/env python3
from typing import TypeVar, Generic, ClassVar, Callable
T = TypeVar("T", float, int) # types supported
class SomeBaseClass(Generic[T]):
"""This base class's some_method will return a supported type."""
RET_TYPE: ClassVar[Callable]
def some_method(self, some_input: str) -> T:
return self.RET_TYPE(some_input)
class SomeChildClass1(SomeBaseClass[float]):
"""This child class's some_method will return a float."""
RET_TYPE = float
class SomeChildClass2(SomeBaseClass[int]):
"""This child class's some_method will return an int."""
RET_TYPE = int
class SomeChildClass3(SomeBaseClass[complex]):
"""This child class's some_method will return a complex."""
RET_TYPE = complex
if __name__ == "__main__":
some_class_1_ret: float = SomeChildClass1().some_method("42")
some_class_2_ret: int = SomeChildClass2().some_method("42")
# PyCharm can infer this return is a complex. However, running mypy on
# this will report (this is desirable to me):
# error: Value of type variable "T" of "SomeBaseClass" cannot be "complex"
some_class_3_ret = SomeChildClass3().some_method("42")
print(
f"some_class_1_ret = {some_class_1_ret} of type {type(some_class_1_ret)}\n"
f"some_class_2_ret = {some_class_2_ret} of type {type(some_class_2_ret)}\n"
f"some_class_3_ret = {some_class_3_ret} of type {type(some_class_3_ret)}\n"
)