Reputation: 1766
Say that I have a function foo
such that it is allowed to take arguments as it follows
foo(a,b) -> It is OK
foo(None,b) -> It is OK
foo (a, None) -> It is OK
foo(None,None) -> It is NOT OK!!!
How to write its signature, including its type hints?
At the moment I have written the type hints as
def foo(a:Optional[str], b:Optional[str]) -> str
but that is wrong because such signature would be fine with the call foo(None,None)
.
Upvotes: 1
Views: 707
Reputation: 71424
Use @overload
to define different (narrower) signatures for a function. Mypy will check calls to that function against all the overloaded signatures and produce an error if none of them match.
from typing import overload, Optional
@overload
def foo(a: str, b: Optional[str]) -> str: ...
@overload
def foo(a: Optional[str], b: str) -> str: ...
def foo(a: Optional[str], b: Optional[str]) -> str:
return (a or "") + (b or "")
foo('a', 'b')
foo(None, 'b')
foo ('a', None)
foo(None, None) # error: No overload variant of "foo" matches argument types "None", "None"
Upvotes: 5