Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 603d354

Browse filesBrowse files
authored
bpo-40493: fix function type comment parsing (GH-19894)
The grammar for func_type_input rejected things like `(*t1) ->t2`. This fixes that. Automerge-Triggered-By: @gvanrossum
1 parent c95e691 commit 603d354
Copy full SHA for 603d354

File tree

Expand file treeCollapse file tree

3 files changed

+78
-0
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+78
-0
lines changed

‎Grammar/python.gram

Copy file name to clipboardExpand all lines: Grammar/python.gram
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ type_expressions[asdl_seq*]:
4040
_PyPegen_seq_append_to_end(p, CHECK(_PyPegen_seq_append_to_end(p, a, b)), c) }
4141
| a=','.expression+ ',' '*' b=expression { _PyPegen_seq_append_to_end(p, a, b) }
4242
| a=','.expression+ ',' '**' b=expression { _PyPegen_seq_append_to_end(p, a, b) }
43+
| '*' a=expression ',' '**' b=expression {
44+
_PyPegen_seq_append_to_end(p, CHECK(_PyPegen_singleton_seq(p, a)), b) }
45+
| '*' a=expression { _PyPegen_singleton_seq(p, a) }
46+
| '**' a=expression { _PyPegen_singleton_seq(p, a) }
4347
| ','.expression+
4448

4549
statements[asdl_seq*]: a=statement+ { _PyPegen_seq_flatten(p, a) }

‎Lib/test/test_type_comments.py

Copy file name to clipboardExpand all lines: Lib/test/test_type_comments.py
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,14 @@ def parse_func_type_input(source):
399399
self.assertEqual(tree.argtypes[2].id, "Any")
400400
self.assertEqual(tree.returns.id, "float")
401401

402+
tree = parse_func_type_input("(*int) -> None")
403+
self.assertEqual(tree.argtypes[0].id, "int")
404+
tree = parse_func_type_input("(**int) -> None")
405+
self.assertEqual(tree.argtypes[0].id, "int")
406+
tree = parse_func_type_input("(*int, **str) -> None")
407+
self.assertEqual(tree.argtypes[0].id, "int")
408+
self.assertEqual(tree.argtypes[1].id, "str")
409+
402410
with self.assertRaises(SyntaxError):
403411
tree = parse_func_type_input("(int, *str, *Any) -> float")
404412

‎Parser/pegen/parse.c

Copy file name to clipboardExpand all lines: Parser/pegen/parse.c
+66Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -825,6 +825,9 @@ fstring_rule(Parser *p)
825825
// | ','.expression+ ',' '*' expression ',' '**' expression
826826
// | ','.expression+ ',' '*' expression
827827
// | ','.expression+ ',' '**' expression
828+
// | '*' expression ',' '**' expression
829+
// | '*' expression
830+
// | '**' expression
828831
// | ','.expression+
829832
static asdl_seq*
830833
type_expressions_rule(Parser *p)
@@ -915,6 +918,69 @@ type_expressions_rule(Parser *p)
915918
}
916919
p->mark = mark;
917920
}
921+
{ // '*' expression ',' '**' expression
922+
expr_ty a;
923+
expr_ty b;
924+
Token * literal;
925+
Token * literal_1;
926+
Token * literal_2;
927+
if (
928+
(literal = _PyPegen_expect_token(p, 16))
929+
&&
930+
(a = expression_rule(p))
931+
&&
932+
(literal_1 = _PyPegen_expect_token(p, 12))
933+
&&
934+
(literal_2 = _PyPegen_expect_token(p, 35))
935+
&&
936+
(b = expression_rule(p))
937+
)
938+
{
939+
res = _PyPegen_seq_append_to_end ( p , CHECK ( _PyPegen_singleton_seq ( p , a ) ) , b );
940+
if (res == NULL && PyErr_Occurred()) {
941+
p->error_indicator = 1;
942+
return NULL;
943+
}
944+
goto done;
945+
}
946+
p->mark = mark;
947+
}
948+
{ // '*' expression
949+
expr_ty a;
950+
Token * literal;
951+
if (
952+
(literal = _PyPegen_expect_token(p, 16))
953+
&&
954+
(a = expression_rule(p))
955+
)
956+
{
957+
res = _PyPegen_singleton_seq ( p , a );
958+
if (res == NULL && PyErr_Occurred()) {
959+
p->error_indicator = 1;
960+
return NULL;
961+
}
962+
goto done;
963+
}
964+
p->mark = mark;
965+
}
966+
{ // '**' expression
967+
expr_ty a;
968+
Token * literal;
969+
if (
970+
(literal = _PyPegen_expect_token(p, 35))
971+
&&
972+
(a = expression_rule(p))
973+
)
974+
{
975+
res = _PyPegen_singleton_seq ( p , a );
976+
if (res == NULL && PyErr_Occurred()) {
977+
p->error_indicator = 1;
978+
return NULL;
979+
}
980+
goto done;
981+
}
982+
p->mark = mark;
983+
}
918984
{ // ','.expression+
919985
asdl_seq * _gather_9_var;
920986
if (

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.