From 2e52e98fd2873775a58616c097e93c96f58fc991 Mon Sep 17 00:00:00 2001 From: Ivan Levkivskyi Date: Fri, 13 Oct 2023 11:30:54 +0100 Subject: [PATCH] Fix crash on ParamSpec unification (for real) (#16259) Fixes https://github.com/python/mypy/issues/16257 Parenthesis strike back. I hope this is the last place where I had put them wrong. --- mypy/expandtype.py | 3 +- .../unit/check-parameter-specification.test | 33 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/mypy/expandtype.py b/mypy/expandtype.py index 4acb51e22268..44716e6da013 100644 --- a/mypy/expandtype.py +++ b/mypy/expandtype.py @@ -348,7 +348,8 @@ def visit_callable_type(self, t: CallableType) -> CallableType: prefix = repl.prefix clean_repl = repl.copy_modified(prefix=Parameters([], [], [])) return t.copy_modified( - arg_types=self.expand_types(t.arg_types[:-2] + prefix.arg_types) + arg_types=self.expand_types(t.arg_types[:-2]) + + prefix.arg_types + [ clean_repl.with_flavor(ParamSpecFlavor.ARGS), clean_repl.with_flavor(ParamSpecFlavor.KWARGS), diff --git a/test-data/unit/check-parameter-specification.test b/test-data/unit/check-parameter-specification.test index bb7859070f00..5b6024da687e 100644 --- a/test-data/unit/check-parameter-specification.test +++ b/test-data/unit/check-parameter-specification.test @@ -2013,3 +2013,36 @@ def event(event_handler: Callable[P, R_co]) -> Callable[P, R_co]: ... @overload def event(namespace: str, *args, **kwargs) -> HandlerDecorator: ... [builtins fixtures/paramspec.pyi] + +[case testParamSpecNoCrashOnUnificationPrefix] +from typing import Any, Callable, TypeVar, overload +from typing_extensions import ParamSpec, Concatenate + +T = TypeVar("T") +U = TypeVar("U") +V = TypeVar("V") +W = TypeVar("W") +P = ParamSpec("P") + +@overload +def call( + func: Callable[Concatenate[T, P], U], + x: T, + *args: Any, + **kwargs: Any, +) -> U: ... +@overload +def call( + func: Callable[Concatenate[T, U, P], V], + x: T, + y: U, + *args: Any, + **kwargs: Any, +) -> V: ... +def call(*args: Any, **kwargs: Any) -> Any: ... + +def test1(x: int) -> str: ... +def test2(x: int, y: int) -> str: ... +reveal_type(call(test1, 1)) # N: Revealed type is "builtins.str" +reveal_type(call(test2, 1, 2)) # N: Revealed type is "builtins.str" +[builtins fixtures/paramspec.pyi]