Skip to content

Commit be17295

Browse files
authored
[3.9] bpo-41697: Correctly handle KeywordOrStarred when parsing arguments in the parser (GH-22077) (GH-22079)
(cherry picked from commit 315a61f) Co-authored-by: Pablo Galindo <Pablogsal@gmail.com>
1 parent a5d0232 commit be17295

File tree

4 files changed

+23
-11
lines changed

4 files changed

+23
-11
lines changed

Grammar/python.gram

+1-1
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,7 @@ arguments[expr_ty] (memo):
537537
| a=args [','] &')' { a }
538538
| incorrect_arguments
539539
args[expr_ty]:
540-
| a=','.(starred_expression | named_expression !'=')+ b=[',' k=kwargs {k}] { _PyPegen_collect_call_seqs(p, a, b) }
540+
| a=','.(starred_expression | named_expression !'=')+ b=[',' k=kwargs {k}] { _PyPegen_collect_call_seqs(p, a, b, EXTRA) }
541541
| a=kwargs { _Py_Call(_PyPegen_dummy_name(p),
542542
CHECK_NULL_ALLOWED(_PyPegen_seq_extract_starred_exprs(p, a)),
543543
CHECK_NULL_ALLOWED(_PyPegen_seq_delete_starred_exprs(p, a)),

Parser/pegen/parse.c

+10-1
Original file line numberDiff line numberDiff line change
@@ -12271,7 +12271,16 @@ args_rule(Parser *p)
1227112271
)
1227212272
{
1227312273
D(fprintf(stderr, "%*c+ args[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.(starred_expression | named_expression !'=')+ [',' kwargs]"));
12274-
_res = _PyPegen_collect_call_seqs ( p , a , b );
12274+
Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
12275+
if (_token == NULL) {
12276+
D(p->level--);
12277+
return NULL;
12278+
}
12279+
int _end_lineno = _token->end_lineno;
12280+
UNUSED(_end_lineno); // Only used by EXTRA macro
12281+
int _end_col_offset = _token->end_col_offset;
12282+
UNUSED(_end_col_offset); // Only used by EXTRA macro
12283+
_res = _PyPegen_collect_call_seqs ( p , a , b , EXTRA );
1227512284
if (_res == NULL && PyErr_Occurred()) {
1227612285
p->error_indicator = 1;
1227712286
D(p->level--);

Parser/pegen/pegen.c

+9-8
Original file line numberDiff line numberDiff line change
@@ -2218,14 +2218,15 @@ _PyPegen_nonparen_genexp_in_call(Parser *p, expr_ty args)
22182218
}
22192219

22202220

2221-
expr_ty _PyPegen_collect_call_seqs(Parser *p, asdl_seq *a, asdl_seq *b) {
2221+
expr_ty _PyPegen_collect_call_seqs(Parser *p, asdl_seq *a, asdl_seq *b,
2222+
int lineno, int col_offset, int end_lineno,
2223+
int end_col_offset, PyArena *arena) {
22222224
Py_ssize_t args_len = asdl_seq_LEN(a);
22232225
Py_ssize_t total_len = args_len;
22242226

22252227
if (b == NULL) {
2226-
expr_ty first = asdl_seq_GET(a, 0);
2227-
expr_ty last = asdl_seq_GET(a, args_len - 1);
2228-
return _Py_Call(_PyPegen_dummy_name(p), a, NULL, EXTRA_EXPR(first, last));
2228+
return _Py_Call(_PyPegen_dummy_name(p), a, NULL, lineno, col_offset,
2229+
end_lineno, end_col_offset, arena);
22292230

22302231
}
22312232

@@ -2236,7 +2237,7 @@ expr_ty _PyPegen_collect_call_seqs(Parser *p, asdl_seq *a, asdl_seq *b) {
22362237
total_len += asdl_seq_LEN(starreds);
22372238
}
22382239

2239-
asdl_seq *args = _Py_asdl_seq_new(total_len, p->arena);
2240+
asdl_seq *args = _Py_asdl_seq_new(total_len, arena);
22402241

22412242
Py_ssize_t i = 0;
22422243
for (i = 0; i < args_len; i++) {
@@ -2246,8 +2247,8 @@ expr_ty _PyPegen_collect_call_seqs(Parser *p, asdl_seq *a, asdl_seq *b) {
22462247
asdl_seq_SET(args, i, asdl_seq_GET(starreds, i - args_len));
22472248
}
22482249

2249-
expr_ty first = asdl_seq_GET(args, 0);
2250-
expr_ty last = asdl_seq_GET(b, asdl_seq_LEN(b)-1);
2250+
return _Py_Call(_PyPegen_dummy_name(p), args, keywords, lineno,
2251+
col_offset, end_lineno, end_col_offset, arena);
2252+
22512253

2252-
return _Py_Call(_PyPegen_dummy_name(p), args, keywords, EXTRA_EXPR(first, last));
22532254
}

Parser/pegen/pegen.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,9 @@ stmt_ty _PyPegen_class_def_decorators(Parser *, asdl_seq *, stmt_ty);
257257
KeywordOrStarred *_PyPegen_keyword_or_starred(Parser *, void *, int);
258258
asdl_seq *_PyPegen_seq_extract_starred_exprs(Parser *, asdl_seq *);
259259
asdl_seq *_PyPegen_seq_delete_starred_exprs(Parser *, asdl_seq *);
260-
expr_ty _PyPegen_collect_call_seqs(Parser *, asdl_seq *, asdl_seq *);
260+
expr_ty _PyPegen_collect_call_seqs(Parser *, asdl_seq *, asdl_seq *,
261+
int lineno, int col_offset, int end_lineno,
262+
int end_col_offset, PyArena *arena);
261263
expr_ty _PyPegen_concatenate_strings(Parser *p, asdl_seq *);
262264
asdl_seq *_PyPegen_join_sequences(Parser *, asdl_seq *, asdl_seq *);
263265
int _PyPegen_check_barry_as_flufl(Parser *);

0 commit comments

Comments
 (0)