Home > OS >  mypy error: Overloaded function signature 2 will never be matched
mypy error: Overloaded function signature 2 will never be matched

Time:05-29

mypy gives this error:

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

with this code:

from typing import overload, Literal
from random import randint

@overload
def func() -> dict[str, float]:
    ...
        
@overload    
def func() -> Literal['']: # this is the error line
    ...

def func() -> dict[str, float] | Literal['']:
    x = randint(1, 10) % 2
    if x:
        return ''
    else:
        return {'foo':12.34}
        
print(func())  

I tried switching the order of the two @overload defs, but that didn't help. I've seen this error message when trying to overload int and float or int and bool, which I can understand given the similarities, but I don't understand the problem here. I also tried str instead of Literal[''] to no avail; similar problems with returning 0 or False. Python 3.10.4 and mypy 0.960.

I'm returning '' in the real code to signal an error.

How to fix?

CodePudding user response:

def func() -> dict[str, float] | Literal['']:

is sufficient. You either return dict or literal depending on if inside the function.

Simply remove the code above. overload would be helpful if you'd have different inputs types and depending on them different output types, while in this example it doesn't depend on input arguments.

CodePudding user response:

As stated in the documentation you linked above, @overload

The @overload decorator allows describing functions and methods that support multiple different combinations of argument types.

It is useful for showing that a function returns different types depending on the types of its arguments. A classic example is __getitem__() which returns a single value if an int is passed as an argument, but returns a list if a slice object is passed as an argument.

In your code, the overloaded func() have the same signature (e.g., no arguments) so mypy can't tell which return type it should use. If mypy is analyzing this code:

x = func()

how does it know the correct return type?

CodePudding user response:

@overload is for functions that accept different types of arguments (as opposed to returning different types). Since func() doesn't take any arguments, you don't need @overload:

from typing import overload, Literal
from random import randint

def func() -> dict[str, float] | Literal['']:
    x = randint(1, 10) % 2
    if x:
        return ''
    else:
        return {'foo':12.34}

print(func())
  • Related