From f1041feefb4f07f194c28a3e0ef72fc9659fb1e4 Mon Sep 17 00:00:00 2001 From: AlexWaygood Date: Sat, 20 Aug 2022 17:16:19 +0100 Subject: [PATCH 1/3] Allow `ParamSpecArgs` to be unpacked --- mypy/checker.py | 3 ++- .../unit/check-parameter-specification.test | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/mypy/checker.py b/mypy/checker.py index c275142c6efb..e426249dc166 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -194,6 +194,7 @@ TypeTranslator, TypeType, TypeVarId, + TypeVarLikeType, TypeVarType, UnboundType, UninhabitedType, @@ -3161,7 +3162,7 @@ def check_multi_assignment( # TODO: maybe elsewhere; redundant. rvalue_type = get_proper_type(rv_type or self.expr_checker.accept(rvalue)) - if isinstance(rvalue_type, TypeVarType): + if isinstance(rvalue_type, TypeVarLikeType): rvalue_type = get_proper_type(rvalue_type.upper_bound) if isinstance(rvalue_type, UnionType): diff --git a/test-data/unit/check-parameter-specification.test b/test-data/unit/check-parameter-specification.test index 18192b38dc6c..4a8b579c300d 100644 --- a/test-data/unit/check-parameter-specification.test +++ b/test-data/unit/check-parameter-specification.test @@ -1092,3 +1092,20 @@ def func(callback: Callable[P, str]) -> Callable[P, str]: return 'baz' return inner [builtins fixtures/paramspec.pyi] + +[case testUnpackingParamsSpecArgsAndKwargs] +from typing import Callable +from typing_extensions import ParamSpec + +P = ParamSpec("P") + +def func(callback: Callable[P, str]) -> Callable[P, str]: + def inner(*args: P.kwargs, **kwargs: P.kwargs) -> str: + a, *b = args + reveal_type(a) # N: Revealed type is "builtins.object" + reveal_type(b) # N: Revealed type is "builtins.list[builtins.object]" + d = {**kwargs} + reveal_type(d) # N: Revealed type is "builtins.dict[builtins.str, builtins.object]" + return "foo" + return inner +[builtins fixtures/paramspec.pyi] From 8d2f686cfea0f4c1e03e1d76c1d26420a0633adb Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Sat, 20 Aug 2022 17:50:53 +0100 Subject: [PATCH 2/3] Update test-data/unit/check-parameter-specification.test --- test-data/unit/check-parameter-specification.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-data/unit/check-parameter-specification.test b/test-data/unit/check-parameter-specification.test index 4a8b579c300d..7209531f2209 100644 --- a/test-data/unit/check-parameter-specification.test +++ b/test-data/unit/check-parameter-specification.test @@ -1100,7 +1100,7 @@ from typing_extensions import ParamSpec P = ParamSpec("P") def func(callback: Callable[P, str]) -> Callable[P, str]: - def inner(*args: P.kwargs, **kwargs: P.kwargs) -> str: + def inner(*args: P.args, **kwargs: P.kwargs) -> str: a, *b = args reveal_type(a) # N: Revealed type is "builtins.object" reveal_type(b) # N: Revealed type is "builtins.list[builtins.object]" From 6ce2658dc92407435fa05df37fd4018baae8d3c6 Mon Sep 17 00:00:00 2001 From: AlexWaygood Date: Sat, 20 Aug 2022 18:15:36 +0100 Subject: [PATCH 3/3] Address @sobolevn's review --- test-data/unit/check-parameter-specification.test | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test-data/unit/check-parameter-specification.test b/test-data/unit/check-parameter-specification.test index 7209531f2209..c3a4216a1eaf 100644 --- a/test-data/unit/check-parameter-specification.test +++ b/test-data/unit/check-parameter-specification.test @@ -1104,8 +1104,11 @@ def func(callback: Callable[P, str]) -> Callable[P, str]: a, *b = args reveal_type(a) # N: Revealed type is "builtins.object" reveal_type(b) # N: Revealed type is "builtins.list[builtins.object]" - d = {**kwargs} - reveal_type(d) # N: Revealed type is "builtins.dict[builtins.str, builtins.object]" + c, *d = kwargs + reveal_type(c) # N: Revealed type is "builtins.str" + reveal_type(d) # N: Revealed type is "builtins.list[builtins.str]" + e = {**kwargs} + reveal_type(e) # N: Revealed type is "builtins.dict[builtins.str, builtins.object]" return "foo" return inner [builtins fixtures/paramspec.pyi]