Reputation: 193
I'm trying to understand how to use the overload decorator when typing functions. If I write the following code and run it through mypy:
from typing import Union, overload
@overload
def myfunc(a: float, b: float) -> float: ...
@overload
def myfunc(a: int, b: int) -> int: ...
def myfunc(a: Union[float, int], b: Union[float, int]) -> Union[float, int]:
return a + b
Then I get a "error: Overloaded function signature 2 will never be matched: signature 1's parameter type(s) are the same or broader Found 1 error in 1 file (checked 1 source file)"
I don't understand why the parameter types of signature 1 (ie. floats) are broader that signature 2 (ie. ints).
What is going on here?
Upvotes: 7
Views: 1835
Reputation: 280181
mypy has a weird special case that treats int
as valid where float
is expected, because requiring people to write Union[int, float]
all over the place would have been awkward enough to seriously hinder adoption of type annotations. That means myfunc(1, 2)
matches both signatures.
When multiple signatures of an overloaded function match a call, mypy will pick the signature defined first. With the way you've written your code, it's impossible for mypy to pick the int
signature. The float
signature will always be picked for any call.
You can fix this by putting the int
signature first:
@overload
def myfunc(a: int, b: int) -> int: ...
@overload
def myfunc(a: float, b: float) -> float: ...
Upvotes: 12