Skip to content

Commit 315a61f

Browse files
authored
bpo-41697: Correctly handle KeywordOrStarred when parsing arguments in the parser (GH-22077)
1 parent 8516060 commit 315a61f

File tree

4 files changed

+23
-11
lines changed

4 files changed

+23
-11
lines changed

Grammar/python.gram

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -535,7 +535,7 @@ arguments[expr_ty] (memo):
535535
| a=args [','] &')' { a }
536536
| incorrect_arguments
537537
args[expr_ty]:
538-
| a=','.(starred_expression | named_expression !'=')+ b=[',' k=kwargs {k}] { _PyPegen_collect_call_seqs(p, a, b) }
538+
| a=','.(starred_expression | named_expression !'=')+ b=[',' k=kwargs {k}] { _PyPegen_collect_call_seqs(p, a, b, EXTRA) }
539539
| a=kwargs { _Py_Call(_PyPegen_dummy_name(p),
540540
CHECK_NULL_ALLOWED(_PyPegen_seq_extract_starred_exprs(p, a)),
541541
CHECK_NULL_ALLOWED(_PyPegen_seq_delete_starred_exprs(p, a)),

Parser/parser.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12237,7 +12237,16 @@ args_rule(Parser *p)
1223712237
)
1223812238
{
1223912239
D(fprintf(stderr, "%*c+ args[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.(starred_expression | named_expression !'=')+ [',' kwargs]"));
12240-
_res = _PyPegen_collect_call_seqs ( p , a , b );
12240+
Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
12241+
if (_token == NULL) {
12242+
D(p->level--);
12243+
return NULL;
12244+
}
12245+
int _end_lineno = _token->end_lineno;
12246+
UNUSED(_end_lineno); // Only used by EXTRA macro
12247+
int _end_col_offset = _token->end_col_offset;
12248+
UNUSED(_end_col_offset); // Only used by EXTRA macro
12249+
_res = _PyPegen_collect_call_seqs ( p , a , b , EXTRA );
1224112250
if (_res == NULL && PyErr_Occurred()) {
1224212251
p->error_indicator = 1;
1224312252
D(p->level--);

Parser/pegen.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2219,14 +2219,15 @@ _PyPegen_nonparen_genexp_in_call(Parser *p, expr_ty args)
22192219
}
22202220

22212221

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

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

22312232
}
22322233

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

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

22422243
Py_ssize_t i = 0;
22432244
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) {
22472248
asdl_seq_SET(args, i, asdl_seq_GET(starreds, i - args_len));
22482249
}
22492250

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

2253-
return _Py_Call(_PyPegen_dummy_name(p), args, keywords, EXTRA_EXPR(first, last));
22542255
}

Parser/pegen.h

Lines changed: 3 additions & 1 deletion
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)