I have a class that accepts either ints or floats in it’s init but all must be int or float so i am using typing.overload to achieve that and I want to be able to type hint the return of a function based on the given values.
class Vector3:
@overload
def __init__(self, x: int, y: int, z: int) -> None:
...
@overload
def __init__(self, x: float, y: float, z: float) -> None:
...
def __init__(self, x, y, z) -> None:
self._x = x
self._y = y
self._z = z
# This function
def __key(self) -> tuple[int | float, int | float, int | float]:
return (self._x, self._y, self._z)
Also how would I type hint the values of x, y, and z? I plan to use @property to obfuscate the _x, _y, _z values and don’t know how I’d type hint them either.
@property
def x(self) -> int | float:
return self._x
>Solution :
Don’t overload __init__ at all. Make Vector3 generic instead, using a constrained type variable.
from typing import Generic, TypeVar
T = TypeVar('T', int, float)
class Vector3(Generic[T]):
def __init__(self, x: T, y: T, z: T) -> None:
self._x: T = x
self._y: T = y
self._z: T = z
def __key(self) -> tuple[T, T, T]:
return (self._x, self._y, self._z)
@property
def x(self) -> T:
return self._x
# etc
Then
reveal_type(Vector3(1, 2, 3)) # Vector3[int]
reveal_type(Vector3(1., 2., 3.)) # Vector3[float]
reveal_type(Vector3(1, 2, 3.)) # Vector3[float], via promotion of int values to floats
reveal_type(Vector3('1', '2', '3')) # type error, T cannot be bound to str
Note that int is considered a subtype of float in this context.