mypy icon indicating copy to clipboard operation
mypy copied to clipboard

functools.partial incorrectly handles generic function arguments

Open tamird opened this issue 1 year ago • 0 comments

Looks like the generic return type is being resolved even before a value of a concrete type is provided.

from typing import Type, TypeVar
import functools

T = TypeVar("T", int, str)

def foo(a: int, b: str, t: Type[T]) -> T: ...

p1 = functools.partial(foo, 1, 2)  # E: Argument 2 to "foo" has incompatible type "int"; expected "str"
p2 = functools.partial(foo, "hello", "world")  # E: Argument 1 to "foo" has incompatible type "str"; expected "int"
p3 = functools.partial(foo, 1, "hello")

reveal_type(p3)  # N: Revealed type is "functools.partial[builtins.int]"  # should still be generic
reveal_type(p3(int))  # N: Revealed type is "builtins.int"
reveal_type(p3(str))  # N: Revealed type is "builtins.int" \
                      # E: Argument 1 to "foo" has incompatible type "Type[str]"; expected "Type[int]"
reveal_type(p3(list))  # N: Revealed type is "builtins.int" \
                       # E: Argument 1 to "foo" has incompatible type "Type[List[Any]]"; expected "Type[int]"

See #17297 for a runnable test case.

tamird avatar Jun 20 '24 21:06 tamird