Closed
Description
Edited with a better example.
Let's suppose you have a function that can take an Optional and returns something based on that or None if it's None.
from typing import overload, Optional
def bar(foo: Optional[int]) -> Optional[str]:
if foo is None:
return None
else:
return str(foo)
x = None # type: Optional[int]
reveal_type(bar(None)) # Line 18
reveal_type(bar(x))
reveal_type(bar('foo'))
There's one problem with this being annotated this way. If you pass a Non-Optional you get returned an Optional[str] even though it's not possible. So I thought the new @overload
stuff might help here but it doesn't:
from typing import overload, Optional
@overload
def bar(foo: int) -> str:
...
@overload
def bar(foo: Optional[int]) -> Optional[str]:
...
def bar(foo: Optional[int]) -> Optional[str]:
if foo is None:
return None
else:
return str(foo)
x = None # type: Optional[int]
reveal_type(bar(None))
reveal_type(bar(x))
reveal_type(bar('foo'))
Sadly that gives me an error and the wrong types:
tt.py:4: error: Overloaded function signatures 1 and 2 overlap with incompatible return types
tt.py:19: error: Revealed type is 'Union[builtins.int, builtins.None]'
tt.py:20: error: Revealed type is 'Any'
tt.py:21: error: Revealed type is 'Any'
I also tried None as the argument to the 2nd overload. That got me closer:
tt.py:19: error: Revealed type is 'Union[builtins.int, builtins.None]'
tt.py:20: error: Revealed type is 'Any'
tt.py:21: error: Revealed type is 'builtins.str'
I would love to be able to specify this as it would make a lot of our code easier to type. Maybe there's a way to do it with a TypeVar but I couldn't figure it out.