Consider the following minimal example in which we have a function foo that can be either called with one int and one string or with two strings:
from typing import overload
@overload
def foo(x: int, y: str) -> str: ...
@overload
def foo(x: str, y: int) -> str: ...
@overload
def foo(x: str, y: str) -> int: ...
def foo(x, y):
if isinstance(x, int):
return str(x - 2) + y
if isinstance(y, int):
return str(y - 2) + x
return int(x + y)
While the implementation of foo should be fine, it is not checked by mypy. So if we should have any type error in the function body, it will not be caught.
So here is my question: Why doesn't mypy simply check the consistency of every signature with the implementation? And how could we make mypy check every signature? Clearly, we can't annotate the implementation like this:
def foo(x: str | int, y: str | int) -> str | int: # mypy complains rightfully
pass
Neither do I see how we could a TypeVar to resolve the issue.
So what should we do?
Some discussion of this can be found in this GitHub issue and in this question. Neither provides a solution for the problem I have described or a satisfying justification for why type checking is "too challenging" for overloaded functions.
**kwargssomewhere, and having partially overlapping types (but not fully, so that every overload is indeed well-defined). Then you need to analyze the function body, and on every call/assignment/return check which of the overloads are in use, and whether the contract is met. If you think it's easy - you may try,mypyalways appreciates contributions. I tried once and gave up after ~800 lines of code and even haven't started addingTypeVarsupport there.overloadis a union from type theory perspective - but more like a distribution of union operation over args). You'll get false positive for combinations that are impossible due to your overloads, but it's better than ignoring the body completely.# type ignore, or is there maybe something smarter we can do?)isinstance(asserts can be optimized away with python interpreter flag, if performance is a real concern here), something like this.