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())