'How to type multiple similar python functions with the same overload signature
I have two functions that are quite similar, the second one calles the first one (and in the actual code does something else afterwards).
Both take two arguments that can take multiple types, bot only certain combinations make sense, therefore I use overload to indicate that (the actual code will also raise for invalid combinations). See the following example:
from typing import overload
@overload
def x(k: int, m: float) -> int:
...
@overload
def x(k: str, m: bytes) -> str:
...
def x(k: int | str, m: float | bytes) -> int | str:
return k
@overload
def y(k: int, m: float) -> int:
...
@overload
def y(k: str, m: bytes) -> str:
...
def y(k: int | str, m: float | bytes) -> int | str:
return x(k, m)
Now mypy complains that:
error: No overload variant of "x" matches argument type "Union[int, str]" [call-overload]
note: Possible overload variants:
note: def x(k: int, m: float) -> int
note: def x(k: str, m: bytes) -> str
What would be the correct way to type such a problem?
Solution 1:[1]
I think you've hit a limitation in python's overload, that while
def y(k: int | str, m: float | bytes) -> int | str:
is the recommended way to write this, it isn't strictly true. It's too broad and I don't believe there's any way round that. You're going to have to narrow the types again at some point between the implementation signature of y and calling x. You could do isinstance checks but since that costs something, I'd personally just # type: ignore[call-overload] this.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
