2Tests the usage of a ParamSpec and its components (P.args, P.kwargs).
5# Specification: https://typing.readthedocs.io/en/latest/spec/generics.html#the-components-of-a-paramspec
8from typing import Any, Callable, Concatenate, ParamSpec, assert_type
13def puts_p_into_scope1(f: Callable[P, int]) -> None:
14 def inner(*args: P.args, **kwargs: P.kwargs) -> None: # OK
17 def mixed_up(*args: P.kwargs, **kwargs: P.args) -> None: # E
[invalid-type-form] `P.kwargs` is valid only in `**kwargs` annotation: Did you mean `P.args`?
[invalid-type-form] `P.args` is valid only in `*args` annotation: Did you mean `P.kwargs`?
20 def misplaced1(x: P.args) -> None: # E
Expected a ty diagnostic for this line
23 def bad_kwargs1(*args: P.args, **kwargs: P.args) -> None: # E
[invalid-type-form] `P.args` is valid only in `*args` annotation: Did you mean `P.kwargs`?
26 def bad_kwargs2(*args: P.args, **kwargs: Any) -> None: # E
Expected a ty diagnostic for this line
30def out_of_scope(*args: P.args, **kwargs: P.kwargs) -> None: # E
Expected a ty diagnostic for this line
34def puts_p_into_scope2(f: Callable[P, int]) -> None:
35 stored_args: P.args # E
Expected a ty diagnostic for this line
36 stored_kwargs: P.kwargs # E
Expected a ty diagnostic for this line
38 def just_args(*args: P.args) -> None: # E
Expected a ty diagnostic for this line
41 def just_kwargs(**kwargs: P.kwargs) -> None: # E
Expected a ty diagnostic for this line
45def decorator(f: Callable[P, int]) -> Callable[P, None]:
46 def foo(*args: P.args, **kwargs: P.kwargs) -> None:
47 assert_type(f(*args, **kwargs), int) # OK
49 f(*kwargs, **args) # E
[invalid-argument-type] Argument is incorrect: Expected `P@decorator.args`, found `P@decorator.kwargs`
[invalid-argument-type] Argument is incorrect: Expected `P@decorator.kwargs`, found `P@decorator.args`
51 f(1, *args, **kwargs) # E
[invalid-argument-type] Argument is incorrect: Expected `P@decorator.args`, found `Literal[1]`
56def add(f: Callable[P, int]) -> Callable[Concatenate[str, P], None]:
57 def foo(s: str, *args: P.args, **kwargs: P.kwargs) -> None: # OK
60 def bar(*args: P.args, s: str, **kwargs: P.kwargs) -> None: # E
Expected a ty diagnostic for this line
66def remove(f: Callable[Concatenate[int, P], int]) -> Callable[P, None]:
67 def foo(*args: P.args, **kwargs: P.kwargs) -> None:
68 f(1, *args, **kwargs) # OK
70 f(*args, 1, **kwargs) # E
Expected a ty diagnostic for this line
72 f(*args, **kwargs) # E
Expected a ty diagnostic for this line
77def outer(f: Callable[P, None]) -> Callable[P, None]:
78 def foo(x: int, *args: P.args, **kwargs: P.kwargs) -> None:
81 def bar(*args: P.args, **kwargs: P.kwargs) -> None:
82 foo(1, *args, **kwargs) # OK
83 foo(x=1, *args, **kwargs) # E
[invalid-argument-type] Argument to function `foo` is incorrect: Expected `int`, found `(...)`
[parameter-already-assigned] Multiple values provided for parameter 1 (`x`) of function `foo`
88def twice(f: Callable[P, int], *args: P.args, **kwargs: P.kwargs) -> int:
89 return f(*args, **kwargs) + f(*args, **kwargs)
92def a_int_b_str(a: int, b: str) -> int:
96twice(a_int_b_str, 1, "A") # OK
97twice(a_int_b_str, b="A", a=1) # OK
98twice(a_int_b_str, "A", 1) # E
[invalid-argument-type] Argument to function `twice` is incorrect: Expected `int`, found `Literal["A"]`
[invalid-argument-type] Argument to function `twice` is incorrect: Expected `str`, found `Literal[1]`