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]"
Looks like the generic return type is being resolved even before a value of a concrete type is provided.
See #17297 for a runnable test case.