Skip to content

functools.partial always assumes the first signature of an @overloaded function #12675

Description

@finite-state-machine

Bug Report

When functools.partial() is applied to an overloaded function, the return type of the first @overload signature is always assumed.

To Reproduce

importfunctoolsfromtypingimport (
Literal,
overload,
Union,
)
@overloaddeffunction(a: Literal[True]) ->int: ...
@overloaddeffunction(a: Literal[False] =False) ->str: ...
deffunction(a: bool=False) ->Union[int, str]:
ifa:
return42else:
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 @overloaded function's implementation (e.g. Union[int, str]). Assuming the return type of the first @overloaded signature is unsound.

Actual Behavior

mypy seems to assume the partial object has the return type of the first @overloaded 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions