]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-40493: fix function type comment parsing (GH-19894)
authorShantanu <hauntsaninja@users.noreply.github.com>
Mon, 4 May 2020 05:08:14 +0000 (22:08 -0700)
committerGitHub <noreply@github.com>
Mon, 4 May 2020 05:08:14 +0000 (22:08 -0700)
The grammar for func_type_input rejected things like `(*t1) ->t2`. This fixes that.

Automerge-Triggered-By: @gvanrossum
Grammar/python.gram
Lib/test/test_type_comments.py
Parser/pegen/parse.c

index cbd4bc010dc1ec820648bf55832b074e1f3cbe55..8e494905cea32cda88cfcbc99a35661affb7e111 100644 (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) }
index 6027b3b56f76f70754f9fd0d28cc97d8f2920852..71d1430dbc939dada0eeeaed9c5f8c46ab1bec84 100644 (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")
 
index b4745ba4d4f26a17abba2562245b13dd1fc7c6ac..492b5e6f9e2b7cdd657b2606f9e3d1c162813aa4 100644 (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 (