The below code fails mypy
with error: Overloaded function signatures 1 and 2 overlap with incompatible return types
.
@overload
def test_overload(x: str) -> str: ...
@overload
def test_overload(x: object) -> int: ...
def test_overload(x) -> Union[str, int]:
if isinstance(x, str):
return x
else:
return 1
What I'm trying to express is: "This function takes an arbitrary Python object. If that object is a string, it returns a string. If it is any other type, it returns an integer. Note this particular example is contrived to represent the general case.
Is it possible to express this with overloads?
At the moment (Python 3.10, mypy 0.961) there is no way to express any object except one. But you could use ignoring type: ignore[misc]
for excepted types. And they must precede the more general variant, because for @overload
order is matter:
from typing import overload, Union
@overload
def test_overload(x: str) -> str: # type: ignore[misc]
...
@overload
def test_overload(x: object) -> int:
...
def test_overload(x) -> Union[str, int]:
if isinstance(x, str):
return x
else:
return 1
reveal_type(test_overload("string")) # Revealed type is "builtins.str"
reveal_type(test_overload(object())) # Revealed type is "builtins.int"