Suppose I have a Python function that varies its return type based on the type of one argument:
def f(a1: int, a2: str, a3: Union[int, str]) -> Union[float, str]:
if isinstance(a3, int):
return float(a1 + a3)
if isinstance(a3, str):
return a2 + a3
I want to use overloading to improve my type annotations:
from typing import overload
@overload
def f(a1: int, a2: str, a3: int) -> float:
...
@overload
def f(a1: int, a2: str, a3: str) -> str:
...
def f(a1, a2, a3):
# ... body ...
This works, but it forced me to repeat the types of a1 and a2 in two separate signatures. This scales very poorly for complex functions with many arguments. I am wondering if there is a way to only once specify the common arguments. Unfortunately this does not work:
from typing import overload
@overload
def f(a1, a2, a3: int) -> float:
...
@overload
def f(a1, a2, a3: str) -> str:
...
def f(a1: int , a2: str, a3): # These annotations aren't used by the overloads
# ... body ...
Is there some way to share type annotations across overload signatures (or otherwise achieve the same objective), or are we stuck repeating ourselves? Note that the above example is contrived, I'm looking for a general solution here that I can use for real-life functions with more complex return type logic.