[Python-checkins] bpo-40493: fix function type comment parsing (GH-19894)
Shantanu
webhook-mailer at python.org
Mon May 4 01:08:22 EDT 2020
https://github.com/python/cpython/commit/603d3546264149f323edb7952b60075fb6bc4dc2
commit: 603d3546264149f323edb7952b60075fb6bc4dc2
branch: master
author: Shantanu <hauntsaninja at users.noreply.github.com>
committer: GitHub <noreply at github.com>
date: 2020-05-03T22:08:14-07:00
summary:
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
files:
M Grammar/python.gram
M Lib/test/test_type_comments.py
M Parser/pegen/parse.c
diff --git a/Grammar/python.gram b/Grammar/python.gram
index cbd4bc010dc1e..8e494905cea32 100644
--- a/Grammar/python.gram
+++ b/Grammar/python.gram
@@ -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) }
diff --git a/Lib/test/test_type_comments.py b/Lib/test/test_type_comments.py
index 6027b3b56f76f..71d1430dbc939 100644
--- a/Lib/test/test_type_comments.py
+++ b/Lib/test/test_type_comments.py
@@ -399,6 +399,14 @@ def parse_func_type_input(source):
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")
diff --git a/Parser/pegen/parse.c b/Parser/pegen/parse.c
index b4745ba4d4f26..492b5e6f9e2b7 100644
--- a/Parser/pegen/parse.c
+++ b/Parser/pegen/parse.c
@@ -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 (
More information about the Python-checkins
mailing list