Andrew Stewart
Andrew Stewart

Reputation: 193

Mypy error: "Overloaded function signature 2 will never be matched: signature 1's parameter type(s) are the same or broader"

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

Answers (1)

user2357112
user2357112

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

Related Questions