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
This commit is contained in:
Shantanu 2020-05-03 22:08:14 -07:00 committed by GitHub
parent c95e691c90
commit 603d354626
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 78 additions and 0 deletions

View File

@ -40,6 +40,10 @@ type_expressions[asdl_seq*]:
_PyPegen_seq_append_to_end(p, CHECK(_PyPegen_seq_append_to_end(p, a, b)), c) }
| a=','.expression+ ',' '*' b=expression { _PyPegen_seq_append_to_end(p, a, b) }
| a=','.expression+ ',' '**' b=expression { _PyPegen_seq_append_to_end(p, a, b) }
| '*' a=expression ',' '**' b=expression {
_PyPegen_seq_append_to_end(p, CHECK(_PyPegen_singleton_seq(p, a)), b) }
| '*' a=expression { _PyPegen_singleton_seq(p, a) }
| '**' a=expression { _PyPegen_singleton_seq(p, a) }
| ','.expression+
statements[asdl_seq*]: a=statement+ { _PyPegen_seq_flatten(p, a) }

View File

@ -399,6 +399,14 @@ class TypeCommentTests(unittest.TestCase):
self.assertEqual(tree.argtypes[2].id, "Any")
self.assertEqual(tree.returns.id, "float")
tree = parse_func_type_input("(*int) -> None")
self.assertEqual(tree.argtypes[0].id, "int")
tree = parse_func_type_input("(**int) -> None")
self.assertEqual(tree.argtypes[0].id, "int")
tree = parse_func_type_input("(*int, **str) -> None")
self.assertEqual(tree.argtypes[0].id, "int")
self.assertEqual(tree.argtypes[1].id, "str")
with self.assertRaises(SyntaxError):
tree = parse_func_type_input("(int, *str, *Any) -> float")

View File

@ -825,6 +825,9 @@ fstring_rule(Parser *p)
// | ','.expression+ ',' '*' expression ',' '**' expression
// | ','.expression+ ',' '*' expression
// | ','.expression+ ',' '**' expression
// | '*' expression ',' '**' expression
// | '*' expression
// | '**' expression
// | ','.expression+
static asdl_seq*
type_expressions_rule(Parser *p)
@ -915,6 +918,69 @@ type_expressions_rule(Parser *p)
}
p->mark = mark;
}
{ // '*' expression ',' '**' expression
expr_ty a;
expr_ty b;
Token * literal;
Token * literal_1;
Token * literal_2;
if (
(literal = _PyPegen_expect_token(p, 16))
&&
(a = expression_rule(p))
&&
(literal_1 = _PyPegen_expect_token(p, 12))
&&
(literal_2 = _PyPegen_expect_token(p, 35))
&&
(b = expression_rule(p))
)
{
res = _PyPegen_seq_append_to_end ( p , CHECK ( _PyPegen_singleton_seq ( p , a ) ) , b );
if (res == NULL && PyErr_Occurred()) {
p->error_indicator = 1;
return NULL;
}
goto done;
}
p->mark = mark;
}
{ // '*' expression
expr_ty a;
Token * literal;
if (
(literal = _PyPegen_expect_token(p, 16))
&&
(a = expression_rule(p))
)
{
res = _PyPegen_singleton_seq ( p , a );
if (res == NULL && PyErr_Occurred()) {
p->error_indicator = 1;
return NULL;
}
goto done;
}
p->mark = mark;
}
{ // '**' expression
expr_ty a;
Token * literal;
if (
(literal = _PyPegen_expect_token(p, 35))
&&
(a = expression_rule(p))
)
{
res = _PyPegen_singleton_seq ( p , a );
if (res == NULL && PyErr_Occurred()) {
p->error_indicator = 1;
return NULL;
}
goto done;
}
p->mark = mark;
}
{ // ','.expression+
asdl_seq * _gather_9_var;
if (