@@ -689,6 +689,7 @@ def func_fn(fn: Callable[P, Tc], b: str) -> Callable[P, Tc]:
689689def func_fn_unpack(fn: Callable[[Unpack[Ts]], Tc], b: str) -> Callable[[Unpack[Ts]], Tc]:
690690 return fn
691691
692+ # We should not leak stray typevars that aren't in scope:
692693use_int_callable(partial(func_b, b=""))
693694use_func_callable(partial(func_b, b=""))
694695use_int_callable(partial(func_c, b=""))
@@ -699,4 +700,29 @@ use_func_callable(partial(func_fn, b=""))
699700use_int_callable(partial(func_fn_unpack, b="")) # E: Argument 1 to "use_int_callable" has incompatible type "partial[Callable[[VarArg(Any)], Any]]"; expected "Callable[[int], int]" \
700701 # N: "partial[Callable[[VarArg(Any)], Any]].__call__" has type "Callable[[VarArg(Any), KwArg(Any)], Callable[[VarArg(Any)], Any]]"
701702use_func_callable(partial(func_fn_unpack, b=""))
703+
704+ # But we should not erase typevars that aren't bound by function
705+ # passed to `partial`:
706+
707+ def outer_b(arg: Tb) -> None:
708+
709+ def inner(a: Tb, b: str) -> Tb:
710+ return a
711+
712+ def call(fn: Callable[[int], int]) -> int:
713+ return fn(0)
714+
715+ call(partial(inner, b="")) # E: Argument 1 to "call" has incompatible type "partial[Tb]"; expected "Callable[[int], int]" \
716+ # N: "partial[Tb].__call__" has type "Callable[[VarArg(Any), KwArg(Any)], Tb]"
717+
718+ def outer_c(arg: Tc) -> None:
719+
720+ def inner(a: Tc, b: str) -> Tc:
721+ return a
722+
723+ def call(fn: Callable[[int], int]) -> int:
724+ return fn(0)
725+
726+ call(partial(inner, b="")) # E: Argument 1 to "call" has incompatible type "partial[str]"; expected "Callable[[int], int]" \
727+ # N: "partial[str].__call__" has type "Callable[[VarArg(Any), KwArg(Any)], str]"
702728[builtins fixtures/tuple.pyi]
0 commit comments