From 315a61f7a9418d904e0eea14b1f054fac3a90e9f Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Thu, 3 Sep 2020 15:29:32 +0100 Subject: bpo-41697: Correctly handle KeywordOrStarred when parsing arguments in the parser (GH-22077) --- Grammar/python.gram | 2 +- Parser/parser.c | 11 ++++++++++- Parser/pegen.c | 17 +++++++++-------- Parser/pegen.h | 4 +++- 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/Grammar/python.gram b/Grammar/python.gram index 84835b7..524e88e 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 3e724a2..8a7cb62 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 2507bc4..4beb2ab 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 3e74e3a..c81681e 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 *); -- cgit v0.12