Barzi2001
Barzi2001

Reputation: 1766

mypy: how to write type hints for a function that takes 2 positional arguments but it is enough that only 1 is passed?

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

Answers (1)

Samwise
Samwise

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

Related Questions