Skip to content

Commit 7ecb7ba

Browse files
committed
bpo-43224: Implement PEP 646 grammar changes
1 parent ce4d25f commit 7ecb7ba

File tree

6 files changed

+2532
-1859
lines changed

6 files changed

+2532
-1859
lines changed

Grammar/python.gram

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,8 @@ slash_with_default[SlashWithDefault*]:
308308
star_etc[StarEtc*]:
309309
| '*' a=param_no_default b=param_maybe_default* c=[kwds] {
310310
_PyPegen_star_etc(p, a, b, c) }
311+
| '*' a=param_no_default_star_annotation b=param_maybe_default* c=[kwds] {
312+
_PyPegen_star_etc(p, a, b, c) }
311313
| '*' ',' b=param_maybe_default+ c=[kwds] {
312314
_PyPegen_star_etc(p, NULL, b, c) }
313315
| a=kwds { _PyPegen_star_etc(p, NULL, NULL, a) }
@@ -331,14 +333,19 @@ kwds[arg_ty]: '**' a=param_no_default { a }
331333
param_no_default[arg_ty]:
332334
| a=param ',' tc=TYPE_COMMENT? { _PyPegen_add_type_comment_to_arg(p, a, tc) }
333335
| a=param tc=TYPE_COMMENT? &')' { _PyPegen_add_type_comment_to_arg(p, a, tc) }
336+
param_no_default_star_annotation[arg_ty]:
337+
| a=param_star_annotation ',' tc=TYPE_COMMENT? { _PyPegen_add_type_comment_to_arg(p, a, tc) }
338+
| a=param_star_annotation tc=TYPE_COMMENT? &')' { _PyPegen_add_type_comment_to_arg(p, a, tc) }
334339
param_with_default[NameDefaultPair*]:
335340
| a=param c=default ',' tc=TYPE_COMMENT? { _PyPegen_name_default_pair(p, a, c, tc) }
336341
| a=param c=default tc=TYPE_COMMENT? &')' { _PyPegen_name_default_pair(p, a, c, tc) }
337342
param_maybe_default[NameDefaultPair*]:
338343
| a=param c=default? ',' tc=TYPE_COMMENT? { _PyPegen_name_default_pair(p, a, c, tc) }
339344
| a=param c=default? tc=TYPE_COMMENT? &')' { _PyPegen_name_default_pair(p, a, c, tc) }
340345
param[arg_ty]: a=NAME b=annotation? { _PyAST_arg(a->v.Name.id, b, NULL, EXTRA) }
346+
param_star_annotation[arg_ty]: a=NAME b=star_annotation { _PyAST_arg(a->v.Name.id, b, NULL, EXTRA) }
341347
annotation[expr_ty]: ':' a=expression { a }
348+
star_annotation[expr_ty]: ':' a=star_expression { a }
342349
default[expr_ty]: '=' a=expression { a }
343350

344351
# If statement
@@ -780,7 +787,7 @@ primary[expr_ty]:
780787

781788
slices[expr_ty]:
782789
| a=slice !',' { a }
783-
| a[asdl_expr_seq*]=','.slice+ [','] { _PyAST_Tuple(a, Load, EXTRA) }
790+
| a[asdl_expr_seq*]=','.(slice | starred_expression)+ [','] { _PyAST_Tuple(a, Load, EXTRA) }
784791

785792
slice[expr_ty]:
786793
| a=[expression] ':' b=[expression] c=[':' d=[expression] { d }] { _PyAST_Slice(a, b, c, EXTRA) }

Lib/test/test_ast.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from test import support
1414

1515
def to_tuple(t):
16-
if t is None or isinstance(t, (str, int, complex)):
16+
if t is None or isinstance(t, (str, int, complex)) or t is Ellipsis:
1717
return t
1818
elif isinstance(t, list):
1919
return [to_tuple(e) for e in t]
@@ -46,10 +46,20 @@ def to_tuple(t):
4646
"def f(a=0): pass",
4747
# FunctionDef with varargs
4848
"def f(*args): pass",
49+
# FunctionDef with varargs as TypeVarTuple
50+
"def f(*args: *Ts): pass",
51+
# FunctionDef with varargs as unpacked Tuple
52+
"def f(*args: *tuple[int, ...]): pass",
53+
# FunctionDef with varargs as unpacked Tuple *and* TypeVarTuple
54+
"def f(*args: *tuple[int, *Ts]): pass",
4955
# FunctionDef with kwargs
5056
"def f(**kwargs): pass",
5157
# FunctionDef with all kind of args and docstring
5258
"def f(a, b=1, c=None, d=[], e={}, *args, f=42, **kwargs): 'doc for f()'",
59+
# FunctionDef with type annotation on return involving unpacking
60+
"def f() -> tuple[*Ts]: pass",
61+
"def f() -> tuple[int, *Ts]: pass",
62+
"def f() -> tuple[int, *tuple[int, ...]]: pass",
5363
# ClassDef
5464
"class C:pass",
5565
# ClassDef with docstring
@@ -65,6 +75,10 @@ def to_tuple(t):
6575
"a,b = c",
6676
"(a,b) = c",
6777
"[a,b] = c",
78+
# AnnAssign with unpacked types
79+
"x: tuple[*Ts]",
80+
"x: tuple[int, *Ts]",
81+
"x: tuple[int, *tuple[str, ...]]",
6882
# AugAssign
6983
"v += 1",
7084
# For
@@ -2316,8 +2330,14 @@ def main():
23162330
('Module', [('FunctionDef', (1, 0, 1, 14), 'f', ('arguments', [], [('arg', (1, 6, 1, 7), 'a', None, None)], None, [], [], None, []), [('Pass', (1, 10, 1, 14))], [], None, None)], []),
23172331
('Module', [('FunctionDef', (1, 0, 1, 16), 'f', ('arguments', [], [('arg', (1, 6, 1, 7), 'a', None, None)], None, [], [], None, [('Constant', (1, 8, 1, 9), 0, None)]), [('Pass', (1, 12, 1, 16))], [], None, None)], []),
23182332
('Module', [('FunctionDef', (1, 0, 1, 18), 'f', ('arguments', [], [], ('arg', (1, 7, 1, 11), 'args', None, None), [], [], None, []), [('Pass', (1, 14, 1, 18))], [], None, None)], []),
2333+
('Module', [('FunctionDef', (1, 0, 1, 23), 'f', ('arguments', [], [], ('arg', (1, 7, 1, 16), 'args', ('Starred', (1, 13, 1, 16), ('Name', (1, 14, 1, 16), 'Ts', ('Load',)), ('Load',)), None), [], [], None, []), [('Pass', (1, 19, 1, 23))], [], None, None)], []),
2334+
('Module', [('FunctionDef', (1, 0, 1, 36), 'f', ('arguments', [], [], ('arg', (1, 7, 1, 29), 'args', ('Starred', (1, 13, 1, 29), ('Subscript', (1, 14, 1, 29), ('Name', (1, 14, 1, 19), 'tuple', ('Load',)), ('Tuple', (1, 20, 1, 28), [('Name', (1, 20, 1, 23), 'int', ('Load',)), ('Constant', (1, 25, 1, 28), Ellipsis, None)], ('Load',)), ('Load',)), ('Load',)), None), [], [], None, []), [('Pass', (1, 32, 1, 36))], [], None, None)], []),
2335+
('Module', [('FunctionDef', (1, 0, 1, 36), 'f', ('arguments', [], [], ('arg', (1, 7, 1, 29), 'args', ('Starred', (1, 13, 1, 29), ('Subscript', (1, 14, 1, 29), ('Name', (1, 14, 1, 19), 'tuple', ('Load',)), ('Tuple', (1, 20, 1, 28), [('Name', (1, 20, 1, 23), 'int', ('Load',)), ('Starred', (1, 25, 1, 28), ('Name', (1, 26, 1, 28), 'Ts', ('Load',)), ('Load',))], ('Load',)), ('Load',)), ('Load',)), None), [], [], None, []), [('Pass', (1, 32, 1, 36))], [], None, None)], []),
23192336
('Module', [('FunctionDef', (1, 0, 1, 21), 'f', ('arguments', [], [], None, [], [], ('arg', (1, 8, 1, 14), 'kwargs', None, None), []), [('Pass', (1, 17, 1, 21))], [], None, None)], []),
23202337
('Module', [('FunctionDef', (1, 0, 1, 71), 'f', ('arguments', [], [('arg', (1, 6, 1, 7), 'a', None, None), ('arg', (1, 9, 1, 10), 'b', None, None), ('arg', (1, 14, 1, 15), 'c', None, None), ('arg', (1, 22, 1, 23), 'd', None, None), ('arg', (1, 28, 1, 29), 'e', None, None)], ('arg', (1, 35, 1, 39), 'args', None, None), [('arg', (1, 41, 1, 42), 'f', None, None)], [('Constant', (1, 43, 1, 45), 42, None)], ('arg', (1, 49, 1, 55), 'kwargs', None, None), [('Constant', (1, 11, 1, 12), 1, None), ('Constant', (1, 16, 1, 20), None, None), ('List', (1, 24, 1, 26), [], ('Load',)), ('Dict', (1, 30, 1, 32), [], [])]), [('Expr', (1, 58, 1, 71), ('Constant', (1, 58, 1, 71), 'doc for f()', None))], [], None, None)], []),
2338+
('Module', [('FunctionDef', (1, 0, 1, 27), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 23, 1, 27))], [], ('Subscript', (1, 11, 1, 21), ('Name', (1, 11, 1, 16), 'tuple', ('Load',)), ('Tuple', (1, 17, 1, 20), [('Starred', (1, 17, 1, 20), ('Name', (1, 18, 1, 20), 'Ts', ('Load',)), ('Load',))], ('Load',)), ('Load',)), None)], []),
2339+
('Module', [('FunctionDef', (1, 0, 1, 32), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 28, 1, 32))], [], ('Subscript', (1, 11, 1, 26), ('Name', (1, 11, 1, 16), 'tuple', ('Load',)), ('Tuple', (1, 17, 1, 25), [('Name', (1, 17, 1, 20), 'int', ('Load',)), ('Starred', (1, 22, 1, 25), ('Name', (1, 23, 1, 25), 'Ts', ('Load',)), ('Load',))], ('Load',)), ('Load',)), None)], []),
2340+
('Module', [('FunctionDef', (1, 0, 1, 45), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 41, 1, 45))], [], ('Subscript', (1, 11, 1, 39), ('Name', (1, 11, 1, 16), 'tuple', ('Load',)), ('Tuple', (1, 17, 1, 38), [('Name', (1, 17, 1, 20), 'int', ('Load',)), ('Starred', (1, 22, 1, 38), ('Subscript', (1, 23, 1, 38), ('Name', (1, 23, 1, 28), 'tuple', ('Load',)), ('Tuple', (1, 29, 1, 37), [('Name', (1, 29, 1, 32), 'int', ('Load',)), ('Constant', (1, 34, 1, 37), Ellipsis, None)], ('Load',)), ('Load',)), ('Load',))], ('Load',)), ('Load',)), None)], []),
23212341
('Module', [('ClassDef', (1, 0, 1, 12), 'C', [], [], [('Pass', (1, 8, 1, 12))], [])], []),
23222342
('Module', [('ClassDef', (1, 0, 1, 32), 'C', [], [], [('Expr', (1, 9, 1, 32), ('Constant', (1, 9, 1, 32), 'docstring for class C', None))], [])], []),
23232343
('Module', [('ClassDef', (1, 0, 1, 21), 'C', [('Name', (1, 8, 1, 14), 'object', ('Load',))], [], [('Pass', (1, 17, 1, 21))], [])], []),
@@ -2327,6 +2347,9 @@ def main():
23272347
('Module', [('Assign', (1, 0, 1, 7), [('Tuple', (1, 0, 1, 3), [('Name', (1, 0, 1, 1), 'a', ('Store',)), ('Name', (1, 2, 1, 3), 'b', ('Store',))], ('Store',))], ('Name', (1, 6, 1, 7), 'c', ('Load',)), None)], []),
23282348
('Module', [('Assign', (1, 0, 1, 9), [('Tuple', (1, 0, 1, 5), [('Name', (1, 1, 1, 2), 'a', ('Store',)), ('Name', (1, 3, 1, 4), 'b', ('Store',))], ('Store',))], ('Name', (1, 8, 1, 9), 'c', ('Load',)), None)], []),
23292349
('Module', [('Assign', (1, 0, 1, 9), [('List', (1, 0, 1, 5), [('Name', (1, 1, 1, 2), 'a', ('Store',)), ('Name', (1, 3, 1, 4), 'b', ('Store',))], ('Store',))], ('Name', (1, 8, 1, 9), 'c', ('Load',)), None)], []),
2350+
('Module', [('AnnAssign', (1, 0, 1, 13), ('Name', (1, 0, 1, 1), 'x', ('Store',)), ('Subscript', (1, 3, 1, 13), ('Name', (1, 3, 1, 8), 'tuple', ('Load',)), ('Tuple', (1, 9, 1, 12), [('Starred', (1, 9, 1, 12), ('Name', (1, 10, 1, 12), 'Ts', ('Load',)), ('Load',))], ('Load',)), ('Load',)), None, 1)], []),
2351+
('Module', [('AnnAssign', (1, 0, 1, 18), ('Name', (1, 0, 1, 1), 'x', ('Store',)), ('Subscript', (1, 3, 1, 18), ('Name', (1, 3, 1, 8), 'tuple', ('Load',)), ('Tuple', (1, 9, 1, 17), [('Name', (1, 9, 1, 12), 'int', ('Load',)), ('Starred', (1, 14, 1, 17), ('Name', (1, 15, 1, 17), 'Ts', ('Load',)), ('Load',))], ('Load',)), ('Load',)), None, 1)], []),
2352+
('Module', [('AnnAssign', (1, 0, 1, 31), ('Name', (1, 0, 1, 1), 'x', ('Store',)), ('Subscript', (1, 3, 1, 31), ('Name', (1, 3, 1, 8), 'tuple', ('Load',)), ('Tuple', (1, 9, 1, 30), [('Name', (1, 9, 1, 12), 'int', ('Load',)), ('Starred', (1, 14, 1, 30), ('Subscript', (1, 15, 1, 30), ('Name', (1, 15, 1, 20), 'tuple', ('Load',)), ('Tuple', (1, 21, 1, 29), [('Name', (1, 21, 1, 24), 'str', ('Load',)), ('Constant', (1, 26, 1, 29), Ellipsis, None)], ('Load',)), ('Load',)), ('Load',))], ('Load',)), ('Load',)), None, 1)], []),
23302353
('Module', [('AugAssign', (1, 0, 1, 6), ('Name', (1, 0, 1, 1), 'v', ('Store',)), ('Add',), ('Constant', (1, 5, 1, 6), 1, None))], []),
23312354
('Module', [('For', (1, 0, 1, 15), ('Name', (1, 4, 1, 5), 'v', ('Store',)), ('Name', (1, 9, 1, 10), 'v', ('Load',)), [('Pass', (1, 11, 1, 15))], [], None)], []),
23322355
('Module', [('While', (1, 0, 1, 12), ('Name', (1, 6, 1, 7), 'v', ('Load',)), [('Pass', (1, 8, 1, 12))], [])], []),

Lib/test/test_pep646_syntax.py

Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
doctests = """
2+
3+
Setup
4+
5+
>>> class AClass:
6+
... def __init__(self):
7+
... self._setitem_name = None
8+
... self._setitem_val = None
9+
... def __setitem__(self, name, val):
10+
... self._setitem_name = name
11+
... self._setitem_val = val
12+
... def __repr__(self):
13+
... return f"A[{self._setitem_name}]={self._setitem_val}"
14+
... def __getitem__(self, name):
15+
... return ParameterisedA(name)
16+
>>> class ParameterisedA:
17+
... def __init__(self, name):
18+
... self._name = name
19+
... def __repr__(self):
20+
... return f"A[{self._name}]"
21+
... def __iter__(self):
22+
... for p in self._name:
23+
... yield p
24+
>>> class B:
25+
... def __iter__(self):
26+
... yield StarredB()
27+
... def __repr__(self):
28+
... return "B"
29+
>>> class StarredB:
30+
... def __repr__(self):
31+
... return "StarredB"
32+
>>> A = AClass()
33+
>>> b = B()
34+
35+
Slices that are supposed to work, starring our custom B class
36+
37+
>>> A[*b]
38+
A[(StarredB,)]
39+
>>> A[*b, *b]
40+
A[(StarredB, StarredB)]
41+
>>> A[b, *b]
42+
A[(B, StarredB)]
43+
>>> A[*b, b]
44+
A[(StarredB, B)]
45+
>>> A[b, b, *b]
46+
A[(B, B, StarredB)]
47+
>>> A[*b, b, b]
48+
A[(StarredB, B, B)]
49+
>>> A[b, *b, b]
50+
A[(B, StarredB, B)]
51+
>>> A[b, b, *b, b]
52+
A[(B, B, StarredB, B)]
53+
>>> A[b, *b, b, b]
54+
A[(B, StarredB, B, B)]
55+
>>> A[A[b, *b, b]]
56+
A[A[(B, StarredB, B)]]
57+
>>> A[*A[b, *b, b]]
58+
A[(B, StarredB, B)]
59+
>>> A[b, ...]
60+
A[(B, Ellipsis)]
61+
>>> A[*A[b, ...]]
62+
A[(B, Ellipsis)]
63+
64+
Slices assignments that are supposed to work, starring our custom B class
65+
66+
>>> A[*b] = 1; A
67+
A[(StarredB,)]=1
68+
>>> A[*b, *b] = 1; A
69+
A[(StarredB, StarredB)]=1
70+
>>> A[b, *b] = 1; A
71+
A[(B, StarredB)]=1
72+
>>> A[*b, b] = 1; A
73+
A[(StarredB, B)]=1
74+
>>> A[b, b, *b] = 1; A
75+
A[(B, B, StarredB)]=1
76+
>>> A[*b, b, b] = 1; A
77+
A[(StarredB, B, B)]=1
78+
>>> A[b, *b, b] = 1; A
79+
A[(B, StarredB, B)]=1
80+
>>> A[b, b, *b, b] = 1; A
81+
A[(B, B, StarredB, B)]=1
82+
>>> A[b, *b, b, b] = 1; A
83+
A[(B, StarredB, B, B)]=1
84+
>>> A[A[b, *b, b]] = 1; A
85+
A[A[(B, StarredB, B)]]=1
86+
>>> A[*A[b, *b, b]] = 1; A
87+
A[(B, StarredB, B)]=1
88+
>>> A[b, ...] = 1; A
89+
A[(B, Ellipsis)]=1
90+
>>> A[*A[b, ...]] = 1; A
91+
A[(B, Ellipsis)]=1
92+
93+
Slices that are supposed to work, starring a list
94+
95+
>>> l = [1, 2, 3]
96+
>>> A[*l]
97+
A[(1, 2, 3)]
98+
>>> A[*l, 4]
99+
A[(1, 2, 3, 4)]
100+
>>> A[0, *l]
101+
A[(0, 1, 2, 3)]
102+
>>> A[1:2, *l]
103+
A[(slice(1, 2, None), 1, 2, 3)]
104+
>>> repr(A[1:2, *l]) == repr(A[1:2, 1, 2, 3])
105+
True
106+
107+
Slice assignments that are supposed to work, starring a list
108+
109+
>>> l = [1, 2, 3]
110+
>>> A[*l] = 1; A
111+
A[(1, 2, 3)]=1
112+
>>> A[*l, 4] = 1; A
113+
A[(1, 2, 3, 4)]=1
114+
>>> A[0, *l] = 1; A
115+
A[(0, 1, 2, 3)]=1
116+
>>> A[1:2, *l] = 1; A
117+
A[(slice(1, 2, None), 1, 2, 3)]=1
118+
119+
Slices that are supposed to work, starring a tuple
120+
121+
>>> t = (1, 2, 3)
122+
>>> A[*t]
123+
A[(1, 2, 3)]
124+
>>> A[*t, 4]
125+
A[(1, 2, 3, 4)]
126+
>>> A[0, *t]
127+
A[(0, 1, 2, 3)]
128+
>>> A[1:2, *t]
129+
A[(slice(1, 2, None), 1, 2, 3)]
130+
>>> repr(A[1:2, *t]) == repr(A[1:2, 1, 2, 3])
131+
True
132+
133+
Slice assignments that are supposed to work, starring a tuple
134+
135+
>>> t = (1, 2, 3)
136+
>>> A[*t] = 1; A
137+
A[(1, 2, 3)]=1
138+
>>> A[*t, 4] = 1; A
139+
A[(1, 2, 3, 4)]=1
140+
>>> A[0, *t] = 1; A
141+
A[(0, 1, 2, 3)]=1
142+
>>> A[1:2, *t] = 1; A
143+
A[(slice(1, 2, None), 1, 2, 3)]=1
144+
145+
Starring an expression (rather than a name) in a slice
146+
147+
>>> def returns_list():
148+
... return [1, 2, 3]
149+
>>> A[returns_list()]
150+
A[[1, 2, 3]]
151+
>>> A[returns_list(), 4]
152+
A[([1, 2, 3], 4)]
153+
>>> A[*returns_list()]
154+
A[(1, 2, 3)]
155+
>>> A[*returns_list(), 4]
156+
A[(1, 2, 3, 4)]
157+
>>> A[0, *returns_list()]
158+
A[(0, 1, 2, 3)]
159+
>>> A[*returns_list(), *returns_list()]
160+
A[(1, 2, 3, 1, 2, 3)]
161+
162+
Starring an expression (rather than a name) in a slice assignment
163+
164+
>>> def returns_list():
165+
... return [1, 2, 3]
166+
>>> A[returns_list()] = 1; A
167+
A[[1, 2, 3]]=1
168+
>>> A[returns_list(), 4] = 1; A
169+
A[([1, 2, 3], 4)]=1
170+
>>> A[*returns_list()] = 1; A
171+
A[(1, 2, 3)]=1
172+
>>> A[*returns_list(), 4] = 1; A
173+
A[(1, 2, 3, 4)]=1
174+
>>> A[0, *returns_list()] = 1; A
175+
A[(0, 1, 2, 3)]=1
176+
>>> A[*returns_list(), *returns_list()] = 1; A
177+
A[(1, 2, 3, 1, 2, 3)]=1
178+
179+
Slices that should fail
180+
181+
>>> A[:*b]
182+
Traceback (most recent call last):
183+
...
184+
SyntaxError: invalid syntax
185+
>>> A[*b:]
186+
Traceback (most recent call last):
187+
...
188+
SyntaxError: invalid syntax
189+
>>> A[*b:*b]
190+
Traceback (most recent call last):
191+
...
192+
SyntaxError: invalid syntax
193+
>>> A[**b]
194+
Traceback (most recent call last):
195+
...
196+
SyntaxError: invalid syntax
197+
198+
Slice assignments that should fail
199+
200+
>>> A[:*b] = 1
201+
Traceback (most recent call last):
202+
...
203+
SyntaxError: invalid syntax
204+
>>> A[*b:] = 1
205+
Traceback (most recent call last):
206+
...
207+
SyntaxError: invalid syntax
208+
>>> A[*b:*b] = 1
209+
Traceback (most recent call last):
210+
...
211+
SyntaxError: invalid syntax
212+
>>> A[**b] = 1
213+
Traceback (most recent call last):
214+
...
215+
SyntaxError: invalid syntax
216+
217+
*args annotated as starred expression
218+
219+
>>> def f1(*args: *b): pass
220+
>>> f1.__annotations__
221+
{'args': StarredB}
222+
223+
>>> def f2(*args: *b, arg1): pass
224+
>>> f2.__annotations__
225+
{'args': StarredB}
226+
227+
>>> def f3(*args: *b, arg1: int): pass
228+
>>> f3.__annotations__
229+
{'args': StarredB, 'arg1': <class 'int'>}
230+
231+
>>> def f4(*args: *b, arg1: int = 2): pass
232+
>>> f4.__annotations__
233+
{'args': StarredB, 'arg1': <class 'int'>}
234+
235+
>>> def f5(*args: *b = (1,)): pass
236+
Traceback (most recent call last):
237+
...
238+
SyntaxError: invalid syntax
239+
240+
Other uses of starred expressions as annotations should fail
241+
242+
>>> def f6(x: *b): pass
243+
Traceback (most recent call last):
244+
...
245+
SyntaxError: invalid syntax
246+
>>> def f7(x: *b = 1): pass
247+
Traceback (most recent call last):
248+
...
249+
SyntaxError: invalid syntax
250+
>>> x: *b
251+
Traceback (most recent call last):
252+
...
253+
SyntaxError: invalid syntax
254+
>>> x: *b = 1
255+
Traceback (most recent call last):
256+
...
257+
SyntaxError: invalid syntax
258+
"""
259+
260+
__test__ = {'doctests' : doctests}
261+
262+
def test_main(verbose=False):
263+
from test import support
264+
from test import test_pep646_syntax
265+
support.run_doctest(test_pep646_syntax, verbose)
266+
267+
if __name__ == "__main__":
268+
test_main(verbose=True)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add support for PEP 646.

0 commit comments

Comments
 (0)