[Python-checkins] bpo-41697: Correctly handle KeywordOrStarred when parsing arguments in the parser (GH-22077)

Pablo Galindo webhook-mailer at python.org
Thu Sep 3 10:29:44 EDT 2020


https://github.com/python/cpython/commit/315a61f7a9418d904e0eea14b1f054fac3a90e9f
commit: 315a61f7a9418d904e0eea14b1f054fac3a90e9f
branch: master
author: Pablo Galindo <Pablogsal at gmail.com>
committer: GitHub <noreply at github.com>
date: 2020-09-03T15:29:32+01:00
summary:

bpo-41697: Correctly handle KeywordOrStarred when parsing arguments in the parser (GH-22077)

files:
M Grammar/python.gram
M Parser/parser.c
M Parser/pegen.c
M Parser/pegen.h

diff --git a/Grammar/python.gram b/Grammar/python.gram
index 84835b731c540..524e88eb38996 100644
--- a/Grammar/python.gram
+++ b/Grammar/python.gram
@@ -535,7 +535,7 @@ arguments[expr_ty] (memo):
     | a=args [','] &')' { a }
     | incorrect_arguments
 args[expr_ty]:
-    | a=','.(starred_expression | named_expression !'=')+ b=[',' k=kwargs {k}] { _PyPegen_collect_call_seqs(p, a, b) }
+    | a=','.(starred_expression | named_expression !'=')+ b=[',' k=kwargs {k}] { _PyPegen_collect_call_seqs(p, a, b, EXTRA) }
     | a=kwargs { _Py_Call(_PyPegen_dummy_name(p),
                           CHECK_NULL_ALLOWED(_PyPegen_seq_extract_starred_exprs(p, a)),
                           CHECK_NULL_ALLOWED(_PyPegen_seq_delete_starred_exprs(p, a)),
diff --git a/Parser/parser.c b/Parser/parser.c
index 3e724a260d90a..8a7cb62fd7cf8 100644
--- a/Parser/parser.c
+++ b/Parser/parser.c
@@ -12237,7 +12237,16 @@ args_rule(Parser *p)
         )
         {
             D(fprintf(stderr, "%*c+ args[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.(starred_expression | named_expression !'=')+ [',' kwargs]"));
-            _res = _PyPegen_collect_call_seqs ( p , a , b );
+            Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
+            if (_token == NULL) {
+                D(p->level--);
+                return NULL;
+            }
+            int _end_lineno = _token->end_lineno;
+            UNUSED(_end_lineno); // Only used by EXTRA macro
+            int _end_col_offset = _token->end_col_offset;
+            UNUSED(_end_col_offset); // Only used by EXTRA macro
+            _res = _PyPegen_collect_call_seqs ( p , a , b , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
                 D(p->level--);
diff --git a/Parser/pegen.c b/Parser/pegen.c
index 2507bc4b38280..4beb2abdd296a 100644
--- a/Parser/pegen.c
+++ b/Parser/pegen.c
@@ -2219,14 +2219,15 @@ _PyPegen_nonparen_genexp_in_call(Parser *p, expr_ty args)
 }
 
 
-expr_ty _PyPegen_collect_call_seqs(Parser *p, asdl_seq *a, asdl_seq *b) {
+expr_ty _PyPegen_collect_call_seqs(Parser *p, asdl_seq *a, asdl_seq *b,
+                     int lineno, int col_offset, int end_lineno,
+                     int end_col_offset, PyArena *arena) {
     Py_ssize_t args_len = asdl_seq_LEN(a);
     Py_ssize_t total_len = args_len;
 
     if (b == NULL) {
-        expr_ty first = asdl_seq_GET(a, 0);
-        expr_ty last = asdl_seq_GET(a, args_len - 1);
-        return _Py_Call(_PyPegen_dummy_name(p), a, NULL, EXTRA_EXPR(first, last));
+        return _Py_Call(_PyPegen_dummy_name(p), a, NULL, lineno, col_offset,
+                        end_lineno, end_col_offset, arena);
 
     }
 
@@ -2237,7 +2238,7 @@ expr_ty _PyPegen_collect_call_seqs(Parser *p, asdl_seq *a, asdl_seq *b) {
         total_len += asdl_seq_LEN(starreds);
     }
 
-    asdl_seq *args = _Py_asdl_seq_new(total_len, p->arena);
+    asdl_seq *args = _Py_asdl_seq_new(total_len, arena);
 
     Py_ssize_t i = 0;
     for (i = 0; i < args_len; i++) {
@@ -2247,8 +2248,8 @@ expr_ty _PyPegen_collect_call_seqs(Parser *p, asdl_seq *a, asdl_seq *b) {
         asdl_seq_SET(args, i, asdl_seq_GET(starreds, i - args_len));
     }
 
-    expr_ty first = asdl_seq_GET(args, 0);
-    expr_ty last = asdl_seq_GET(b, asdl_seq_LEN(b)-1);
+    return _Py_Call(_PyPegen_dummy_name(p), args, keywords, lineno,
+                    col_offset, end_lineno, end_col_offset, arena);
+
 
-    return _Py_Call(_PyPegen_dummy_name(p), args, keywords, EXTRA_EXPR(first, last));
 }
diff --git a/Parser/pegen.h b/Parser/pegen.h
index 3e74e3ac73e0a..c81681efad208 100644
--- a/Parser/pegen.h
+++ b/Parser/pegen.h
@@ -257,7 +257,9 @@ stmt_ty _PyPegen_class_def_decorators(Parser *, asdl_seq *, stmt_ty);
 KeywordOrStarred *_PyPegen_keyword_or_starred(Parser *, void *, int);
 asdl_seq *_PyPegen_seq_extract_starred_exprs(Parser *, asdl_seq *);
 asdl_seq *_PyPegen_seq_delete_starred_exprs(Parser *, asdl_seq *);
-expr_ty _PyPegen_collect_call_seqs(Parser *, asdl_seq *, asdl_seq *);
+expr_ty _PyPegen_collect_call_seqs(Parser *, asdl_seq *, asdl_seq *,
+                     int lineno, int col_offset, int end_lineno,
+                     int end_col_offset, PyArena *arena);
 expr_ty _PyPegen_concatenate_strings(Parser *p, asdl_seq *);
 asdl_seq *_PyPegen_join_sequences(Parser *, asdl_seq *, asdl_seq *);
 int _PyPegen_check_barry_as_flufl(Parser *);



More information about the Python-checkins mailing list