functools.partial always assumes the first signature of an @overloaded function #12675
Closed
Description
Bug Report
When functools.partial()
is applied to an overloaded function, the return type of the first @overload
signature is always assumed.
To Reproduce
import functools
from typing import (
Literal,
overload,
Union,
)
@overload
def function(a: Literal[True]) -> int: ...
@overload
def function(a: Literal[False] = False) -> str: ...
def function(a: bool = False) -> Union[int, str]:
if a:
return 42
else:
return 'hello'
p0 = functools.partial(function)
reveal_type(p0)
# actual: Revealed type is "functools.partial[builtins.int*]"
# expected: Revealed type is "functools.partial[Union[int, str]]"
# (because 'p0()' would accept any value for 'a')
v0 = p0()
reveal_type(v0)
# actual: Revealed type is "builtins.int*"
# expected: either "str" or "Union[int, str]"
# (the latter is less precise, but at least it's not wrong)
p1 = functools.partial(function, a=False)
reveal_type(p1)
# actual: Revealed type is "functools.partial[builtins.int*]"
# expected: Revealed type is "functools.partial[Union[int, str]]"
# (because 'p1()' can still accept any value for 'a' if given as a kwarg;
# 'functools.partial()' defaults can be overridden)
p2 = functools.partial(function, a=True)
reveal_type(p2)
# actual: Revealed type is "functools.partial[builtins.int*]"
# expected: Revealed type is "functools.partial[Union[int, str]]"
# (by similar logic)
Expected Behavior
If mypy cannot intelligently handle the interaction of @overload
and functools.partial()
(i.e., the partial object has overloaded behaviour), it should at least assume the return type of the partial is that of the @overload
ed function's implementation (e.g. Union[int, str]
). Assuming the return type of the first @overload
ed signature is unsound.
Actual Behavior
mypy seems to assume the partial
object has the return type of the first @overload
ed signature, regardless of the arguments. Other signatures and the implementation signature are ignored.
Your Environment
- Mypy version used: 0.942
- Mypy command-line flags: (none)
- Mypy configuration options from
mypy.ini
(and other config files): (none) - Python version used: 3.8
- Operating system and version: macOS 10.14