-
Notifications
You must be signed in to change notification settings - Fork 249
/
Copy pathgenerics_paramspec_components.py
98 lines (58 loc) · 2.33 KB
/
generics_paramspec_components.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
"""
Tests the usage of a ParamSpec and its components (P.args, P.kwargs).
"""
# Specification: https://typing.readthedocs.io/en/latest/spec/generics.html#the-components-of-a-paramspec
from typing import Any, Callable, Concatenate, ParamSpec, assert_type
P = ParamSpec("P")
def puts_p_into_scope1(f: Callable[P, int]) -> None:
def inner(*args: P.args, **kwargs: P.kwargs) -> None: # OK
pass
def mixed_up(*args: P.kwargs, **kwargs: P.args) -> None: # E
pass
def misplaced1(x: P.args) -> None: # E
pass
def bad_kwargs1(*args: P.args, **kwargs: P.args) -> None: # E
pass
def bad_kwargs2(*args: P.args, **kwargs: Any) -> None: # E
pass
def out_of_scope(*args: P.args, **kwargs: P.kwargs) -> None: # E
pass
def puts_p_into_scope2(f: Callable[P, int]) -> None:
stored_args: P.args # E
stored_kwargs: P.kwargs # E
def just_args(*args: P.args) -> None: # E
pass
def just_kwargs(**kwargs: P.kwargs) -> None: # E
pass
def decorator(f: Callable[P, int]) -> Callable[P, None]:
def foo(*args: P.args, **kwargs: P.kwargs) -> None:
assert_type(f(*args, **kwargs), int) # OK
f(*kwargs, **args) # E
f(1, *args, **kwargs) # E
return foo # OK
def add(f: Callable[P, int]) -> Callable[Concatenate[str, P], None]:
def foo(s: str, *args: P.args, **kwargs: P.kwargs) -> None: # OK
pass
def bar(*args: P.args, s: str, **kwargs: P.kwargs) -> None: # E
pass
return foo # OK
def remove(f: Callable[Concatenate[int, P], int]) -> Callable[P, None]:
def foo(*args: P.args, **kwargs: P.kwargs) -> None:
f(1, *args, **kwargs) # OK
f(*args, 1, **kwargs) # E
f(*args, **kwargs) # E
return foo # OK
def outer(f: Callable[P, None]) -> Callable[P, None]:
def foo(x: int, *args: P.args, **kwargs: P.kwargs) -> None:
f(*args, **kwargs)
def bar(*args: P.args, **kwargs: P.kwargs) -> None:
foo(1, *args, **kwargs) # OK
foo(x=1, *args, **kwargs) # E
return bar
def twice(f: Callable[P, int], *args: P.args, **kwargs: P.kwargs) -> int:
return f(*args, **kwargs) + f(*args, **kwargs)
def a_int_b_str(a: int, b: str) -> int:
return 0
twice(a_int_b_str, 1, "A") # OK
twice(a_int_b_str, b="A", a=1) # OK
twice(a_int_b_str, "A", 1) # E