Coverage Report

Created: 2026-10-31 06:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cpython/Parser/action_helpers.c
Line
Count
Source
1
#include <Python.h>
2
#include "pycore_pystate.h"         // _PyInterpreterState_GET()
3
#include "pycore_runtime.h"         // _PyRuntime
4
#include "pycore_unicodeobject.h"   // _PyUnicode_InternImmortal()
5
#include "pycore_pyerrors.h"        // _PyErr_EmitSyntaxWarning()
6
7
#include "pegen.h"
8
#include "string_parser.h"          // _PyPegen_decode_string()
9
#include "lexer/state.h"            // tok_state
10
11
12
void *
13
_PyPegen_dummy_name(Parser *p, ...)
14
66.7k
{
15
66.7k
    return &_PyRuntime.parser.dummy_name;
16
66.7k
}
17
18
/* Creates a single-element asdl_seq* that contains a */
19
asdl_seq *
20
_PyPegen_singleton_seq(Parser *p, void *a)
21
134k
{
22
134k
    assert(a != NULL);
23
134k
    asdl_seq *seq = (asdl_seq*)_Py_asdl_generic_seq_new(1, p->arena);
24
134k
    if (!seq) {
25
0
        return NULL;
26
0
    }
27
134k
    asdl_seq_SET_UNTYPED(seq, 0, a);
28
134k
    return seq;
29
134k
}
30
31
/* Creates a copy of seq and prepends a to it */
32
asdl_seq *
33
_PyPegen_seq_insert_in_front(Parser *p, void *a, asdl_seq *seq)
34
326k
{
35
326k
    assert(a != NULL);
36
326k
    if (!seq) {
37
6.31k
        return _PyPegen_singleton_seq(p, a);
38
6.31k
    }
39
40
319k
    asdl_seq *new_seq = (asdl_seq*)_Py_asdl_generic_seq_new(asdl_seq_LEN(seq) + 1, p->arena);
41
319k
    if (!new_seq) {
42
0
        return NULL;
43
0
    }
44
45
319k
    asdl_seq_SET_UNTYPED(new_seq, 0, a);
46
568k
    for (Py_ssize_t i = 1, l = asdl_seq_LEN(new_seq); i < l; i++) {
47
248k
        asdl_seq_SET_UNTYPED(new_seq, i, asdl_seq_GET_UNTYPED(seq, i - 1));
48
248k
    }
49
319k
    return new_seq;
50
319k
}
51
52
/* Creates a copy of seq and appends a to it */
53
asdl_seq *
54
_PyPegen_seq_append_to_end(Parser *p, asdl_seq *seq, void *a)
55
0
{
56
0
    assert(a != NULL);
57
0
    if (!seq) {
58
0
        return _PyPegen_singleton_seq(p, a);
59
0
    }
60
61
0
    asdl_seq *new_seq = (asdl_seq*)_Py_asdl_generic_seq_new(asdl_seq_LEN(seq) + 1, p->arena);
62
0
    if (!new_seq) {
63
0
        return NULL;
64
0
    }
65
66
0
    for (Py_ssize_t i = 0, l = asdl_seq_LEN(new_seq); i + 1 < l; i++) {
67
0
        asdl_seq_SET_UNTYPED(new_seq, i, asdl_seq_GET_UNTYPED(seq, i));
68
0
    }
69
0
    asdl_seq_SET_UNTYPED(new_seq, asdl_seq_LEN(new_seq) - 1, a);
70
0
    return new_seq;
71
0
}
72
73
static Py_ssize_t
74
_get_flattened_seq_size(asdl_seq *seqs)
75
18.5k
{
76
18.5k
    Py_ssize_t size = 0;
77
105k
    for (Py_ssize_t i = 0, l = asdl_seq_LEN(seqs); i < l; i++) {
78
86.8k
        asdl_seq *inner_seq = asdl_seq_GET_UNTYPED(seqs, i);
79
86.8k
        size += asdl_seq_LEN(inner_seq);
80
86.8k
    }
81
18.5k
    return size;
82
18.5k
}
83
84
/* Flattens an asdl_seq* of asdl_seq*s */
85
asdl_seq *
86
_PyPegen_seq_flatten(Parser *p, asdl_seq *seqs)
87
18.5k
{
88
18.5k
    Py_ssize_t flattened_seq_size = _get_flattened_seq_size(seqs);
89
18.5k
    assert(flattened_seq_size > 0);
90
91
18.5k
    asdl_seq *flattened_seq = (asdl_seq*)_Py_asdl_generic_seq_new(flattened_seq_size, p->arena);
92
18.5k
    if (!flattened_seq) {
93
0
        return NULL;
94
0
    }
95
96
18.5k
    int flattened_seq_idx = 0;
97
105k
    for (Py_ssize_t i = 0, l = asdl_seq_LEN(seqs); i < l; i++) {
98
86.8k
        asdl_seq *inner_seq = asdl_seq_GET_UNTYPED(seqs, i);
99
191k
        for (Py_ssize_t j = 0, li = asdl_seq_LEN(inner_seq); j < li; j++) {
100
104k
            asdl_seq_SET_UNTYPED(flattened_seq, flattened_seq_idx++, asdl_seq_GET_UNTYPED(inner_seq, j));
101
104k
        }
102
86.8k
    }
103
18.5k
    assert(flattened_seq_idx == flattened_seq_size);
104
105
18.5k
    return flattened_seq;
106
18.5k
}
107
108
void *
109
_PyPegen_seq_last_item(asdl_seq *seq)
110
68
{
111
68
    Py_ssize_t len = asdl_seq_LEN(seq);
112
68
    return asdl_seq_GET_UNTYPED(seq, len - 1);
113
68
}
114
115
void *
116
_PyPegen_seq_first_item(asdl_seq *seq)
117
34
{
118
34
    return asdl_seq_GET_UNTYPED(seq, 0);
119
34
}
120
121
/* Creates a new name of the form <first_name>.<second_name> */
122
expr_ty
123
_PyPegen_join_names_with_dot(Parser *p, expr_ty first_name, expr_ty second_name)
124
4.61k
{
125
4.61k
    assert(first_name != NULL && second_name != NULL);
126
4.61k
    PyObject *uni = PyUnicode_FromFormat("%U.%U",
127
4.61k
            first_name->v.Name.id, second_name->v.Name.id);
128
4.61k
    if (!uni) {
129
0
        return NULL;
130
0
    }
131
4.61k
    PyInterpreterState *interp = _PyInterpreterState_GET();
132
4.61k
    _PyUnicode_InternImmortal(interp, &uni);
133
4.61k
    if (_PyArena_AddPyObject(p->arena, uni) < 0) {
134
0
        Py_DECREF(uni);
135
0
        return NULL;
136
0
    }
137
138
4.61k
    return _PyAST_Name(uni, Load, EXTRA_EXPR(first_name, second_name));
139
4.61k
}
140
141
/* Counts the total number of dots in seq's tokens */
142
int
143
_PyPegen_seq_count_dots(asdl_seq *seq)
144
5.97k
{
145
5.97k
    int number_of_dots = 0;
146
20.4k
    for (Py_ssize_t i = 0, l = asdl_seq_LEN(seq); i < l; i++) {
147
14.4k
        Token *current_expr = asdl_seq_GET_UNTYPED(seq, i);
148
14.4k
        switch (current_expr->type) {
149
6.20k
            case ELLIPSIS:
150
6.20k
                number_of_dots += 3;
151
6.20k
                break;
152
8.25k
            case DOT:
153
8.25k
                number_of_dots += 1;
154
8.25k
                break;
155
0
            default:
156
0
                Py_UNREACHABLE();
157
14.4k
        }
158
14.4k
    }
159
160
5.97k
    return number_of_dots;
161
5.97k
}
162
163
/* Creates an alias with '*' as the identifier name */
164
alias_ty
165
_PyPegen_alias_for_star(Parser *p, int lineno, int col_offset, int end_lineno,
166
1.74k
                        int end_col_offset, PyArena *arena) {
167
1.74k
    PyObject *str = PyUnicode_InternFromString("*");
168
1.74k
    if (!str) {
169
0
        return NULL;
170
0
    }
171
1.74k
    if (_PyArena_AddPyObject(p->arena, str) < 0) {
172
0
        Py_DECREF(str);
173
0
        return NULL;
174
0
    }
175
1.74k
    return _PyAST_alias(str, NULL, lineno, col_offset, end_lineno, end_col_offset, arena);
176
1.74k
}
177
178
/* Creates a new asdl_seq* with the identifiers of all the names in seq */
179
asdl_identifier_seq *
180
_PyPegen_map_names_to_ids(Parser *p, asdl_expr_seq *seq)
181
1.95k
{
182
1.95k
    Py_ssize_t len = asdl_seq_LEN(seq);
183
1.95k
    assert(len > 0);
184
185
1.95k
    asdl_identifier_seq *new_seq = _Py_asdl_identifier_seq_new(len, p->arena);
186
1.95k
    if (!new_seq) {
187
0
        return NULL;
188
0
    }
189
6.82k
    for (Py_ssize_t i = 0; i < len; i++) {
190
4.87k
        expr_ty e = asdl_seq_GET(seq, i);
191
4.87k
        asdl_seq_SET(new_seq, i, e->v.Name.id);
192
4.87k
    }
193
1.95k
    return new_seq;
194
1.95k
}
195
196
/* Constructs a CmpopExprPair */
197
CmpopExprPair *
198
_PyPegen_cmpop_expr_pair(Parser *p, cmpop_ty cmpop, expr_ty expr)
199
18.5k
{
200
18.5k
    assert(expr != NULL);
201
18.5k
    CmpopExprPair *a = _PyArena_Malloc(p->arena, sizeof(CmpopExprPair));
202
18.5k
    if (!a) {
203
0
        return NULL;
204
0
    }
205
18.5k
    a->cmpop = cmpop;
206
18.5k
    a->expr = expr;
207
18.5k
    return a;
208
18.5k
}
209
210
asdl_int_seq *
211
_PyPegen_get_cmpops(Parser *p, asdl_seq *seq)
212
5.70k
{
213
5.70k
    Py_ssize_t len = asdl_seq_LEN(seq);
214
5.70k
    assert(len > 0);
215
216
5.70k
    asdl_int_seq *new_seq = _Py_asdl_int_seq_new(len, p->arena);
217
5.70k
    if (!new_seq) {
218
0
        return NULL;
219
0
    }
220
23.6k
    for (Py_ssize_t i = 0; i < len; i++) {
221
17.9k
        CmpopExprPair *pair = asdl_seq_GET_UNTYPED(seq, i);
222
17.9k
        asdl_seq_SET(new_seq, i, pair->cmpop);
223
17.9k
    }
224
5.70k
    return new_seq;
225
5.70k
}
226
227
asdl_expr_seq *
228
_PyPegen_get_exprs(Parser *p, asdl_seq *seq)
229
5.70k
{
230
5.70k
    Py_ssize_t len = asdl_seq_LEN(seq);
231
5.70k
    assert(len > 0);
232
233
5.70k
    asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena);
234
5.70k
    if (!new_seq) {
235
0
        return NULL;
236
0
    }
237
23.6k
    for (Py_ssize_t i = 0; i < len; i++) {
238
17.9k
        CmpopExprPair *pair = asdl_seq_GET_UNTYPED(seq, i);
239
17.9k
        asdl_seq_SET(new_seq, i, pair->expr);
240
17.9k
    }
241
5.70k
    return new_seq;
242
5.70k
}
243
244
/* Creates an asdl_seq* where all the elements have been changed to have ctx as context */
245
static asdl_expr_seq *
246
_set_seq_context(Parser *p, asdl_expr_seq *seq, expr_context_ty ctx)
247
6.01k
{
248
6.01k
    Py_ssize_t len = asdl_seq_LEN(seq);
249
6.01k
    if (len == 0) {
250
4.53k
        return NULL;
251
4.53k
    }
252
253
1.48k
    asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena);
254
1.48k
    if (!new_seq) {
255
0
        return NULL;
256
0
    }
257
4.04k
    for (Py_ssize_t i = 0; i < len; i++) {
258
2.55k
        expr_ty e = asdl_seq_GET(seq, i);
259
2.55k
        expr_ty new_e = _PyPegen_set_expr_context(p, e, ctx);
260
2.55k
        if (!new_e) {
261
0
            return NULL;
262
0
        }
263
2.55k
        asdl_seq_SET(new_seq, i, new_e);
264
2.55k
    }
265
1.48k
    return new_seq;
266
1.48k
}
267
268
static expr_ty
269
_set_name_context(Parser *p, expr_ty e, expr_context_ty ctx)
270
186k
{
271
186k
    return _PyAST_Name(e->v.Name.id, ctx, EXTRA_EXPR(e, e));
272
186k
}
273
274
static expr_ty
275
_set_tuple_context(Parser *p, expr_ty e, expr_context_ty ctx)
276
4.58k
{
277
4.58k
    asdl_expr_seq *seq = _set_seq_context(p, e->v.Tuple.elts, ctx);
278
4.58k
    if (!seq && PyErr_Occurred()) {
279
0
        return NULL;
280
0
    }
281
4.58k
    return _PyAST_Tuple(seq, ctx, EXTRA_EXPR(e, e));
282
4.58k
}
283
284
static expr_ty
285
_set_list_context(Parser *p, expr_ty e, expr_context_ty ctx)
286
1.43k
{
287
1.43k
    asdl_expr_seq *seq = _set_seq_context(p, e->v.List.elts, ctx);
288
1.43k
    if (!seq && PyErr_Occurred()) {
289
0
        return NULL;
290
0
    }
291
1.43k
    return _PyAST_List(seq, ctx, EXTRA_EXPR(e, e));
292
1.43k
}
293
294
static expr_ty
295
_set_subscript_context(Parser *p, expr_ty e, expr_context_ty ctx)
296
1.31k
{
297
1.31k
    return _PyAST_Subscript(e->v.Subscript.value, e->v.Subscript.slice,
298
1.31k
                            ctx, EXTRA_EXPR(e, e));
299
1.31k
}
300
301
static expr_ty
302
_set_attribute_context(Parser *p, expr_ty e, expr_context_ty ctx)
303
5.78k
{
304
5.78k
    return _PyAST_Attribute(e->v.Attribute.value, e->v.Attribute.attr,
305
5.78k
                            ctx, EXTRA_EXPR(e, e));
306
5.78k
}
307
308
static expr_ty
309
_set_starred_context(Parser *p, expr_ty e, expr_context_ty ctx)
310
215
{
311
215
    expr_ty inner = _PyPegen_set_expr_context(p, e->v.Starred.value, ctx);
312
215
    if (!inner) {
313
0
        return NULL;
314
0
    }
315
215
    return _PyAST_Starred(inner, ctx, EXTRA_EXPR(e, e));
316
215
}
317
318
/* Creates an `expr_ty` equivalent to `expr` but with `ctx` as context */
319
expr_ty
320
_PyPegen_set_expr_context(Parser *p, expr_ty expr, expr_context_ty ctx)
321
200k
{
322
200k
    assert(expr != NULL);
323
324
200k
    expr_ty new = NULL;
325
200k
    switch (expr->kind) {
326
186k
        case Name_kind:
327
186k
            new = _set_name_context(p, expr, ctx);
328
186k
            break;
329
4.58k
        case Tuple_kind:
330
4.58k
            new = _set_tuple_context(p, expr, ctx);
331
4.58k
            break;
332
1.43k
        case List_kind:
333
1.43k
            new = _set_list_context(p, expr, ctx);
334
1.43k
            break;
335
1.31k
        case Subscript_kind:
336
1.31k
            new = _set_subscript_context(p, expr, ctx);
337
1.31k
            break;
338
5.78k
        case Attribute_kind:
339
5.78k
            new = _set_attribute_context(p, expr, ctx);
340
5.78k
            break;
341
215
        case Starred_kind:
342
215
            new = _set_starred_context(p, expr, ctx);
343
215
            break;
344
0
        default:
345
0
            new = expr;
346
200k
    }
347
200k
    return new;
348
200k
}
349
350
/* Invalid targets return NULL without raising, allowing parsing to backtrack.
351
   Copy valid targets to preserve the memoized expression's context. */
352
expr_ty
353
_PyPegen_make_target(Parser *p, expr_ty expr, TARGETS_TYPE targets_type)
354
367k
{
355
367k
    assert(expr != NULL);
356
367k
    assert(targets_type != FOR_TARGETS);
357
367k
    if (_PyPegen_get_invalid_target(expr, targets_type) != NULL) {
358
192k
        return NULL;
359
192k
    }
360
174k
    return _PyPegen_set_expr_context(
361
174k
        p, expr, targets_type == DEL_TARGETS ? Del : Store);
362
367k
}
363
364
/* Constructs a KeyValuePair that is used when parsing a dict's key value pairs */
365
KeyValuePair *
366
_PyPegen_key_value_pair(Parser *p, expr_ty key, expr_ty value)
367
31.0k
{
368
31.0k
    KeyValuePair *a = _PyArena_Malloc(p->arena, sizeof(KeyValuePair));
369
31.0k
    if (!a) {
370
0
        return NULL;
371
0
    }
372
31.0k
    a->key = key;
373
31.0k
    a->value = value;
374
31.0k
    return a;
375
31.0k
}
376
377
/* Extracts all keys from an asdl_seq* of KeyValuePair*'s */
378
asdl_expr_seq *
379
_PyPegen_get_keys(Parser *p, asdl_seq *seq)
380
4.03k
{
381
4.03k
    Py_ssize_t len = asdl_seq_LEN(seq);
382
4.03k
    asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena);
383
4.03k
    if (!new_seq) {
384
0
        return NULL;
385
0
    }
386
21.0k
    for (Py_ssize_t i = 0; i < len; i++) {
387
16.9k
        KeyValuePair *pair = asdl_seq_GET_UNTYPED(seq, i);
388
16.9k
        asdl_seq_SET(new_seq, i, pair->key);
389
16.9k
    }
390
4.03k
    return new_seq;
391
4.03k
}
392
393
/* Extracts all values from an asdl_seq* of KeyValuePair*'s */
394
asdl_expr_seq *
395
_PyPegen_get_values(Parser *p, asdl_seq *seq)
396
4.03k
{
397
4.03k
    Py_ssize_t len = asdl_seq_LEN(seq);
398
4.03k
    asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena);
399
4.03k
    if (!new_seq) {
400
0
        return NULL;
401
0
    }
402
21.0k
    for (Py_ssize_t i = 0; i < len; i++) {
403
16.9k
        KeyValuePair *pair = asdl_seq_GET_UNTYPED(seq, i);
404
16.9k
        asdl_seq_SET(new_seq, i, pair->value);
405
16.9k
    }
406
4.03k
    return new_seq;
407
4.03k
}
408
409
/* Constructs a KeyPatternPair that is used when parsing mapping & class patterns */
410
KeyPatternPair *
411
_PyPegen_key_pattern_pair(Parser *p, expr_ty key, pattern_ty pattern)
412
13.5k
{
413
13.5k
    KeyPatternPair *a = _PyArena_Malloc(p->arena, sizeof(KeyPatternPair));
414
13.5k
    if (!a) {
415
0
        return NULL;
416
0
    }
417
13.5k
    a->key = key;
418
13.5k
    a->pattern = pattern;
419
13.5k
    return a;
420
13.5k
}
421
422
/* Extracts all keys from an asdl_seq* of KeyPatternPair*'s */
423
asdl_expr_seq *
424
_PyPegen_get_pattern_keys(Parser *p, asdl_seq *seq)
425
1.55k
{
426
1.55k
    Py_ssize_t len = asdl_seq_LEN(seq);
427
1.55k
    asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena);
428
1.55k
    if (!new_seq) {
429
0
        return NULL;
430
0
    }
431
4.03k
    for (Py_ssize_t i = 0; i < len; i++) {
432
2.47k
        KeyPatternPair *pair = asdl_seq_GET_UNTYPED(seq, i);
433
2.47k
        asdl_seq_SET(new_seq, i, pair->key);
434
2.47k
    }
435
1.55k
    return new_seq;
436
1.55k
}
437
438
/* Extracts all patterns from an asdl_seq* of KeyPatternPair*'s */
439
asdl_pattern_seq *
440
_PyPegen_get_patterns(Parser *p, asdl_seq *seq)
441
1.55k
{
442
1.55k
    Py_ssize_t len = asdl_seq_LEN(seq);
443
1.55k
    asdl_pattern_seq *new_seq = _Py_asdl_pattern_seq_new(len, p->arena);
444
1.55k
    if (!new_seq) {
445
0
        return NULL;
446
0
    }
447
4.03k
    for (Py_ssize_t i = 0; i < len; i++) {
448
2.47k
        KeyPatternPair *pair = asdl_seq_GET_UNTYPED(seq, i);
449
2.47k
        asdl_seq_SET(new_seq, i, pair->pattern);
450
2.47k
    }
451
1.55k
    return new_seq;
452
1.55k
}
453
454
/* Constructs a NameDefaultPair */
455
NameDefaultPair *
456
_PyPegen_name_default_pair(Parser *p, arg_ty arg, expr_ty value, Token *tc)
457
401k
{
458
401k
    NameDefaultPair *a = _PyArena_Malloc(p->arena, sizeof(NameDefaultPair));
459
401k
    if (!a) {
460
0
        return NULL;
461
0
    }
462
401k
    a->arg = _PyPegen_add_type_comment_to_arg(p, arg, tc);
463
401k
    if (!a->arg) {
464
0
        return NULL;
465
0
    }
466
401k
    a->value = value;
467
401k
    return a;
468
401k
}
469
470
/* Constructs a SlashWithDefault */
471
SlashWithDefault *
472
_PyPegen_slash_with_default(Parser *p, asdl_arg_seq *plain_names, asdl_seq *names_with_defaults)
473
5.61k
{
474
5.61k
    SlashWithDefault *a = _PyArena_Malloc(p->arena, sizeof(SlashWithDefault));
475
5.61k
    if (!a) {
476
0
        return NULL;
477
0
    }
478
5.61k
    a->plain_names = plain_names;
479
5.61k
    a->names_with_defaults = names_with_defaults;
480
5.61k
    return a;
481
5.61k
}
482
483
/* Constructs a StarEtc */
484
StarEtc *
485
_PyPegen_star_etc(Parser *p, arg_ty vararg, asdl_seq *kwonlyargs, arg_ty kwarg)
486
6.77k
{
487
6.77k
    StarEtc *a = _PyArena_Malloc(p->arena, sizeof(StarEtc));
488
6.77k
    if (!a) {
489
0
        return NULL;
490
0
    }
491
6.77k
    a->vararg = vararg;
492
6.77k
    a->kwonlyargs = kwonlyargs;
493
6.77k
    a->kwarg = kwarg;
494
6.77k
    return a;
495
6.77k
}
496
497
asdl_seq *
498
_PyPegen_join_sequences(Parser *p, asdl_seq *a, asdl_seq *b)
499
221k
{
500
221k
    Py_ssize_t first_len = asdl_seq_LEN(a);
501
221k
    Py_ssize_t second_len = asdl_seq_LEN(b);
502
221k
    asdl_seq *new_seq = (asdl_seq*)_Py_asdl_generic_seq_new(first_len + second_len, p->arena);
503
221k
    if (!new_seq) {
504
0
        return NULL;
505
0
    }
506
507
221k
    int k = 0;
508
454k
    for (Py_ssize_t i = 0; i < first_len; i++) {
509
233k
        asdl_seq_SET_UNTYPED(new_seq, k++, asdl_seq_GET_UNTYPED(a, i));
510
233k
    }
511
232k
    for (Py_ssize_t i = 0; i < second_len; i++) {
512
11.2k
        asdl_seq_SET_UNTYPED(new_seq, k++, asdl_seq_GET_UNTYPED(b, i));
513
11.2k
    }
514
515
221k
    return new_seq;
516
221k
}
517
518
static asdl_arg_seq*
519
_get_names(Parser *p, asdl_seq *names_with_defaults)
520
228k
{
521
228k
    Py_ssize_t len = asdl_seq_LEN(names_with_defaults);
522
228k
    asdl_arg_seq *seq = _Py_asdl_arg_seq_new(len, p->arena);
523
228k
    if (!seq) {
524
0
        return NULL;
525
0
    }
526
245k
    for (Py_ssize_t i = 0; i < len; i++) {
527
17.1k
        NameDefaultPair *pair = asdl_seq_GET_UNTYPED(names_with_defaults, i);
528
17.1k
        asdl_seq_SET(seq, i, pair->arg);
529
17.1k
    }
530
228k
    return seq;
531
228k
}
532
533
static asdl_expr_seq *
534
_get_defaults(Parser *p, asdl_seq *names_with_defaults)
535
228k
{
536
228k
    Py_ssize_t len = asdl_seq_LEN(names_with_defaults);
537
228k
    asdl_expr_seq *seq = _Py_asdl_expr_seq_new(len, p->arena);
538
228k
    if (!seq) {
539
0
        return NULL;
540
0
    }
541
245k
    for (Py_ssize_t i = 0; i < len; i++) {
542
17.1k
        NameDefaultPair *pair = asdl_seq_GET_UNTYPED(names_with_defaults, i);
543
17.1k
        asdl_seq_SET(seq, i, pair->value);
544
17.1k
    }
545
228k
    return seq;
546
228k
}
547
548
static int
549
_make_posonlyargs(Parser *p,
550
                  asdl_arg_seq *slash_without_default,
551
                  SlashWithDefault *slash_with_default,
552
227k
                  asdl_arg_seq **posonlyargs) {
553
227k
    if (slash_without_default != NULL) {
554
1.44k
        *posonlyargs = slash_without_default;
555
1.44k
    }
556
226k
    else if (slash_with_default != NULL) {
557
1.79k
        asdl_arg_seq *slash_with_default_names =
558
1.79k
                _get_names(p, slash_with_default->names_with_defaults);
559
1.79k
        if (!slash_with_default_names) {
560
0
            return -1;
561
0
        }
562
1.79k
        *posonlyargs = (asdl_arg_seq*)_PyPegen_join_sequences(
563
1.79k
                p,
564
1.79k
                (asdl_seq*)slash_with_default->plain_names,
565
1.79k
                (asdl_seq*)slash_with_default_names);
566
1.79k
    }
567
224k
    else {
568
224k
        *posonlyargs = _Py_asdl_arg_seq_new(0, p->arena);
569
224k
    }
570
227k
    return *posonlyargs == NULL ? -1 : 0;
571
227k
}
572
573
static int
574
_make_posargs(Parser *p,
575
              asdl_arg_seq *plain_names,
576
              asdl_seq *names_with_default,
577
227k
              asdl_arg_seq **posargs) {
578
579
227k
    if (names_with_default != NULL) {
580
221k
        if (plain_names != NULL) {
581
217k
            asdl_arg_seq *names_with_default_names = _get_names(p, names_with_default);
582
217k
            if (!names_with_default_names) {
583
0
                return -1;
584
0
            }
585
217k
            *posargs = (asdl_arg_seq*)_PyPegen_join_sequences(
586
217k
                    p,(asdl_seq*)plain_names, (asdl_seq*)names_with_default_names);
587
217k
        }
588
4.20k
        else {
589
4.20k
            *posargs = _get_names(p, names_with_default);
590
4.20k
        }
591
221k
    }
592
6.26k
    else {
593
6.26k
        if (plain_names != NULL) {
594
            // With the current grammar, we never get here.
595
            // If that has changed, remove the assert, and test thoroughly.
596
0
            assert(0);
597
0
            *posargs = plain_names;
598
0
        }
599
6.26k
        else {
600
6.26k
            *posargs = _Py_asdl_arg_seq_new(0, p->arena);
601
6.26k
        }
602
6.26k
    }
603
227k
    return *posargs == NULL ? -1 : 0;
604
227k
}
605
606
static int
607
_make_posdefaults(Parser *p,
608
                  SlashWithDefault *slash_with_default,
609
                  asdl_seq *names_with_default,
610
227k
                  asdl_expr_seq **posdefaults) {
611
227k
    if (slash_with_default != NULL && names_with_default != NULL) {
612
1.79k
        asdl_expr_seq *slash_with_default_values =
613
1.79k
                _get_defaults(p, slash_with_default->names_with_defaults);
614
1.79k
        if (!slash_with_default_values) {
615
0
            return -1;
616
0
        }
617
1.79k
        asdl_expr_seq *names_with_default_values = _get_defaults(p, names_with_default);
618
1.79k
        if (!names_with_default_values) {
619
0
            return -1;
620
0
        }
621
1.79k
        *posdefaults = (asdl_expr_seq*)_PyPegen_join_sequences(
622
1.79k
                p,
623
1.79k
                (asdl_seq*)slash_with_default_values,
624
1.79k
                (asdl_seq*)names_with_default_values);
625
1.79k
    }
626
225k
    else if (slash_with_default == NULL && names_with_default != NULL) {
627
219k
        *posdefaults = _get_defaults(p, names_with_default);
628
219k
    }
629
6.26k
    else if (slash_with_default != NULL && names_with_default == NULL) {
630
0
        *posdefaults = _get_defaults(p, slash_with_default->names_with_defaults);
631
0
    }
632
6.26k
    else {
633
6.26k
        *posdefaults = _Py_asdl_expr_seq_new(0, p->arena);
634
6.26k
    }
635
227k
    return *posdefaults == NULL ? -1 : 0;
636
227k
}
637
638
static int
639
_make_kwargs(Parser *p, StarEtc *star_etc,
640
             asdl_arg_seq **kwonlyargs,
641
227k
             asdl_expr_seq **kwdefaults) {
642
227k
    if (star_etc != NULL && star_etc->kwonlyargs != NULL) {
643
5.21k
        *kwonlyargs = _get_names(p, star_etc->kwonlyargs);
644
5.21k
    }
645
222k
    else {
646
222k
        *kwonlyargs = _Py_asdl_arg_seq_new(0, p->arena);
647
222k
    }
648
649
227k
    if (*kwonlyargs == NULL) {
650
0
        return -1;
651
0
    }
652
653
227k
    if (star_etc != NULL && star_etc->kwonlyargs != NULL) {
654
5.21k
        *kwdefaults = _get_defaults(p, star_etc->kwonlyargs);
655
5.21k
    }
656
222k
    else {
657
222k
        *kwdefaults = _Py_asdl_expr_seq_new(0, p->arena);
658
222k
    }
659
660
227k
    if (*kwdefaults == NULL) {
661
0
        return -1;
662
0
    }
663
664
227k
    return 0;
665
227k
}
666
667
/* Constructs an arguments_ty object out of all the parsed constructs in the parameters rule */
668
arguments_ty
669
_PyPegen_make_arguments(Parser *p, asdl_arg_seq *slash_without_default,
670
                        SlashWithDefault *slash_with_default, asdl_arg_seq *plain_names,
671
                        asdl_seq *names_with_default, StarEtc *star_etc)
672
227k
{
673
227k
    asdl_arg_seq *posonlyargs;
674
227k
    if (_make_posonlyargs(p, slash_without_default, slash_with_default, &posonlyargs) == -1) {
675
0
        return NULL;
676
0
    }
677
678
227k
    asdl_arg_seq *posargs;
679
227k
    if (_make_posargs(p, plain_names, names_with_default, &posargs) == -1) {
680
0
        return NULL;
681
0
    }
682
683
227k
    asdl_expr_seq *posdefaults;
684
227k
    if (_make_posdefaults(p,slash_with_default, names_with_default, &posdefaults) == -1) {
685
0
        return NULL;
686
0
    }
687
688
227k
    arg_ty vararg = NULL;
689
227k
    if (star_etc != NULL && star_etc->vararg != NULL) {
690
4.01k
        vararg = star_etc->vararg;
691
4.01k
    }
692
693
227k
    asdl_arg_seq *kwonlyargs;
694
227k
    asdl_expr_seq *kwdefaults;
695
227k
    if (_make_kwargs(p, star_etc, &kwonlyargs, &kwdefaults) == -1) {
696
0
        return NULL;
697
0
    }
698
699
227k
    arg_ty kwarg = NULL;
700
227k
    if (star_etc != NULL && star_etc->kwarg != NULL) {
701
1.58k
        kwarg = star_etc->kwarg;
702
1.58k
    }
703
704
227k
    return _PyAST_arguments(posonlyargs, posargs, vararg, kwonlyargs,
705
227k
                            kwdefaults, kwarg, posdefaults, p->arena);
706
227k
}
707
708
709
/* Constructs an empty arguments_ty object, that gets used when a function accepts no
710
 * arguments. */
711
arguments_ty
712
_PyPegen_empty_arguments(Parser *p)
713
2.61k
{
714
2.61k
    asdl_arg_seq *posonlyargs = _Py_asdl_arg_seq_new(0, p->arena);
715
2.61k
    if (!posonlyargs) {
716
0
        return NULL;
717
0
    }
718
2.61k
    asdl_arg_seq *posargs = _Py_asdl_arg_seq_new(0, p->arena);
719
2.61k
    if (!posargs) {
720
0
        return NULL;
721
0
    }
722
2.61k
    asdl_expr_seq *posdefaults = _Py_asdl_expr_seq_new(0, p->arena);
723
2.61k
    if (!posdefaults) {
724
0
        return NULL;
725
0
    }
726
2.61k
    asdl_arg_seq *kwonlyargs = _Py_asdl_arg_seq_new(0, p->arena);
727
2.61k
    if (!kwonlyargs) {
728
0
        return NULL;
729
0
    }
730
2.61k
    asdl_expr_seq *kwdefaults = _Py_asdl_expr_seq_new(0, p->arena);
731
2.61k
    if (!kwdefaults) {
732
0
        return NULL;
733
0
    }
734
735
2.61k
    return _PyAST_arguments(posonlyargs, posargs, NULL, kwonlyargs,
736
2.61k
                            kwdefaults, NULL, posdefaults, p->arena);
737
2.61k
}
738
739
/* Encapsulates the value of an operator_ty into an AugOperator struct */
740
AugOperator *
741
_PyPegen_augoperator(Parser *p, operator_ty kind)
742
3.55k
{
743
3.55k
    AugOperator *a = _PyArena_Malloc(p->arena, sizeof(AugOperator));
744
3.55k
    if (!a) {
745
0
        return NULL;
746
0
    }
747
3.55k
    a->kind = kind;
748
3.55k
    return a;
749
3.55k
}
750
751
/* Construct a FunctionDef equivalent to function_def, but with decorators */
752
stmt_ty
753
_PyPegen_function_def_decorators(Parser *p, asdl_expr_seq *decorators, stmt_ty function_def)
754
638
{
755
638
    assert(function_def != NULL);
756
638
    if (function_def->kind == AsyncFunctionDef_kind) {
757
312
        return _PyAST_AsyncFunctionDef(
758
312
            function_def->v.AsyncFunctionDef.name,
759
312
            function_def->v.AsyncFunctionDef.args,
760
312
            function_def->v.AsyncFunctionDef.body, decorators,
761
312
            function_def->v.AsyncFunctionDef.returns,
762
312
            function_def->v.AsyncFunctionDef.type_comment,
763
312
            function_def->v.AsyncFunctionDef.type_params,
764
312
            function_def->lineno, function_def->col_offset,
765
312
            function_def->end_lineno, function_def->end_col_offset, p->arena);
766
312
    }
767
768
326
    return _PyAST_FunctionDef(
769
326
        function_def->v.FunctionDef.name,
770
326
        function_def->v.FunctionDef.args,
771
326
        function_def->v.FunctionDef.body, decorators,
772
326
        function_def->v.FunctionDef.returns,
773
326
        function_def->v.FunctionDef.type_comment,
774
326
        function_def->v.FunctionDef.type_params,
775
326
        function_def->lineno, function_def->col_offset,
776
326
        function_def->end_lineno, function_def->end_col_offset, p->arena);
777
638
}
778
779
/* Construct a ClassDef equivalent to class_def, but with decorators */
780
stmt_ty
781
_PyPegen_class_def_decorators(Parser *p, asdl_expr_seq *decorators, stmt_ty class_def)
782
319
{
783
319
    assert(class_def != NULL);
784
319
    return _PyAST_ClassDef(
785
319
        class_def->v.ClassDef.name,
786
319
        class_def->v.ClassDef.bases, class_def->v.ClassDef.keywords,
787
319
        class_def->v.ClassDef.body, decorators,
788
319
        class_def->v.ClassDef.type_params,
789
319
        class_def->lineno, class_def->col_offset, class_def->end_lineno,
790
319
        class_def->end_col_offset, p->arena);
791
319
}
792
793
/* Construct a KeywordOrStarred */
794
KeywordOrStarred *
795
_PyPegen_keyword_or_starred(Parser *p, void *element, int is_keyword)
796
28.3k
{
797
28.3k
    KeywordOrStarred *a = _PyArena_Malloc(p->arena, sizeof(KeywordOrStarred));
798
28.3k
    if (!a) {
799
0
        return NULL;
800
0
    }
801
28.3k
    a->element = element;
802
28.3k
    a->is_keyword = is_keyword;
803
28.3k
    return a;
804
28.3k
}
805
806
/* Get the number of starred expressions in an asdl_seq* of KeywordOrStarred*s */
807
static int
808
_seq_number_of_starred_exprs(asdl_seq *seq)
809
20.1k
{
810
20.1k
    int n = 0;
811
65.8k
    for (Py_ssize_t i = 0, l = asdl_seq_LEN(seq); i < l; i++) {
812
45.6k
        KeywordOrStarred *k = asdl_seq_GET_UNTYPED(seq, i);
813
45.6k
        if (!k->is_keyword) {
814
4.34k
            n++;
815
4.34k
        }
816
45.6k
    }
817
20.1k
    return n;
818
20.1k
}
819
820
/* Extract the starred expressions of an asdl_seq* of KeywordOrStarred*s */
821
asdl_expr_seq *
822
_PyPegen_seq_extract_starred_exprs(Parser *p, asdl_seq *kwargs)
823
10.0k
{
824
10.0k
    int new_len = _seq_number_of_starred_exprs(kwargs);
825
10.0k
    if (new_len == 0) {
826
9.41k
        return NULL;
827
9.41k
    }
828
679
    asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(new_len, p->arena);
829
679
    if (!new_seq) {
830
0
        return NULL;
831
0
    }
832
833
679
    int idx = 0;
834
3.98k
    for (Py_ssize_t i = 0, len = asdl_seq_LEN(kwargs); i < len; i++) {
835
3.30k
        KeywordOrStarred *k = asdl_seq_GET_UNTYPED(kwargs, i);
836
3.30k
        if (!k->is_keyword) {
837
2.17k
            asdl_seq_SET(new_seq, idx++, k->element);
838
2.17k
        }
839
3.30k
    }
840
679
    return new_seq;
841
679
}
842
843
/* Return a new asdl_seq* with only the keywords in kwargs */
844
asdl_keyword_seq*
845
_PyPegen_seq_delete_starred_exprs(Parser *p, asdl_seq *kwargs)
846
10.0k
{
847
10.0k
    Py_ssize_t len = asdl_seq_LEN(kwargs);
848
10.0k
    Py_ssize_t new_len = len - _seq_number_of_starred_exprs(kwargs);
849
10.0k
    if (new_len == 0) {
850
0
        return NULL;
851
0
    }
852
10.0k
    asdl_keyword_seq *new_seq = _Py_asdl_keyword_seq_new(new_len, p->arena);
853
10.0k
    if (!new_seq) {
854
0
        return NULL;
855
0
    }
856
857
10.0k
    int idx = 0;
858
32.9k
    for (Py_ssize_t i = 0; i < len; i++) {
859
22.8k
        KeywordOrStarred *k = asdl_seq_GET_UNTYPED(kwargs, i);
860
22.8k
        if (k->is_keyword) {
861
20.6k
            asdl_seq_SET(new_seq, idx++, k->element);
862
20.6k
        }
863
22.8k
    }
864
10.0k
    return new_seq;
865
10.0k
}
866
867
expr_ty
868
_PyPegen_ensure_imaginary(Parser *p, expr_ty exp)
869
1.47k
{
870
1.47k
    if (exp->kind != Constant_kind || !PyComplex_CheckExact(exp->v.Constant.value)) {
871
7
        RAISE_SYNTAX_ERROR_KNOWN_LOCATION(exp, "imaginary number required in complex literal");
872
7
        return NULL;
873
7
    }
874
1.47k
    return exp;
875
1.47k
}
876
877
expr_ty
878
_PyPegen_ensure_real(Parser *p, expr_ty exp)
879
3.40k
{
880
3.40k
    if (exp->kind != Constant_kind || PyComplex_CheckExact(exp->v.Constant.value)) {
881
4
        RAISE_SYNTAX_ERROR_KNOWN_LOCATION(exp, "real number required in complex literal");
882
4
        return NULL;
883
4
    }
884
3.39k
    return exp;
885
3.40k
}
886
887
mod_ty
888
8.12k
_PyPegen_make_module(Parser *p, asdl_stmt_seq *a) {
889
8.12k
    asdl_type_ignore_seq *type_ignores = NULL;
890
8.12k
    Py_ssize_t num = p->type_ignore_comments.num_items;
891
8.12k
    if (num > 0) {
892
        // Turn the raw (comment, lineno) pairs into TypeIgnore objects in the arena
893
0
        type_ignores = _Py_asdl_type_ignore_seq_new(num, p->arena);
894
0
        if (type_ignores == NULL) {
895
0
            return NULL;
896
0
        }
897
0
        for (Py_ssize_t i = 0; i < num; i++) {
898
0
            PyObject *tag = _PyPegen_new_type_comment(p, p->type_ignore_comments.items[i].comment);
899
0
            if (tag == NULL) {
900
0
                return NULL;
901
0
            }
902
0
            type_ignore_ty ti = _PyAST_TypeIgnore(p->type_ignore_comments.items[i].lineno,
903
0
                                                  tag, p->arena);
904
0
            if (ti == NULL) {
905
0
                return NULL;
906
0
            }
907
0
            asdl_seq_SET(type_ignores, i, ti);
908
0
        }
909
0
    }
910
8.12k
    return _PyAST_Module(a, type_ignores, p->arena);
911
8.12k
}
912
913
PyObject *
914
_PyPegen_new_type_comment(Parser *p, const char *s)
915
0
{
916
0
    PyObject *res = PyUnicode_DecodeUTF8(s, strlen(s), NULL);
917
0
    if (res == NULL) {
918
0
        return NULL;
919
0
    }
920
0
    if (_PyArena_AddPyObject(p->arena, res) < 0) {
921
0
        Py_DECREF(res);
922
0
        return NULL;
923
0
    }
924
0
    return res;
925
0
}
926
927
arg_ty
928
_PyPegen_add_type_comment_to_arg(Parser *p, arg_ty a, Token *tc)
929
469k
{
930
469k
    if (tc == NULL) {
931
469k
        return a;
932
469k
    }
933
0
    const char *bytes = PyBytes_AsString(tc->bytes);
934
0
    if (bytes == NULL) {
935
0
        return NULL;
936
0
    }
937
0
    PyObject *tco = _PyPegen_new_type_comment(p, bytes);
938
0
    if (tco == NULL) {
939
0
        return NULL;
940
0
    }
941
0
    return _PyAST_arg(a->arg, a->annotation, tco,
942
0
                      a->lineno, a->col_offset, a->end_lineno, a->end_col_offset,
943
0
                      p->arena);
944
0
}
945
946
/* Checks if the NOTEQUAL token is valid given the current parser flags
947
0 indicates success and nonzero indicates failure (an exception may be set) */
948
int
949
1.20k
_PyPegen_check_barry_as_flufl(Parser *p, Token* t) {
950
1.20k
    assert(t->bytes != NULL);
951
1.20k
    assert(t->type == NOTEQUAL);
952
953
1.20k
    const char* tok_str = PyBytes_AS_STRING(t->bytes);
954
1.20k
    if (p->flags & PyPARSE_BARRY_AS_BDFL && strcmp(tok_str, "<>") != 0) {
955
1
        RAISE_SYNTAX_ERROR("with Barry as BDFL, use '<>' instead of '!='");
956
1
        return -1;
957
1
    }
958
1.20k
    if (!(p->flags & PyPARSE_BARRY_AS_BDFL)) {
959
1.01k
        return strcmp(tok_str, "!=");
960
1.01k
    }
961
194
    return 0;
962
1.20k
}
963
964
int
965
12.5k
_PyPegen_check_legacy_stmt(Parser *p, expr_ty name) {
966
12.5k
    if (name->kind != Name_kind) {
967
3.47k
        return 0;
968
3.47k
    }
969
9.05k
    const char* candidates[2] = {"print", "exec"};
970
26.9k
    for (int i=0; i<2; i++) {
971
18.1k
        if (PyUnicode_CompareWithASCIIString(name->v.Name.id, candidates[i]) == 0) {
972
215
            return 1;
973
215
        }
974
18.1k
    }
975
8.83k
    return 0;
976
9.05k
}
977
978
void *
979
_PyPegen_raise_error_for_missing_comma(Parser *p, expr_ty a, expr_ty b)
980
6.11k
{
981
    // Don't raise for legacy statements like "print x" or "exec x"
982
6.11k
    if (_PyPegen_check_legacy_stmt(p, a)) {
983
204
        return NULL;
984
204
    }
985
    // Only raise inside parentheses/brackets (level > 0)
986
5.91k
    if (p->tokens[p->mark - 1]->level == 0) {
987
5.77k
        return NULL;
988
5.77k
    }
989
    // For multi-line expressions (like string concatenations), point to the
990
    // last line instead of the first for a more helpful error message.
991
    // Use a->col_offset as the starting column since all strings in the
992
    // concatenation typically share the same indentation.
993
141
    if (a->end_lineno > a->lineno) {
994
6
        return RAISE_ERROR_KNOWN_LOCATION(
995
6
            p, PyExc_SyntaxError, a->end_lineno, a->col_offset,
996
6
            a->end_lineno, a->end_col_offset,
997
6
            "invalid syntax. Perhaps you forgot a comma?"
998
6
        );
999
6
    }
1000
135
    return RAISE_ERROR_KNOWN_LOCATION(
1001
135
        p, PyExc_SyntaxError, a->lineno, a->col_offset,
1002
135
        b->end_lineno, b->end_col_offset,
1003
135
        "invalid syntax. Perhaps you forgot a comma?"
1004
135
    );
1005
141
}
1006
1007
static ResultTokenWithMetadata *
1008
result_token_with_metadata(Parser *p, void *result, PyObject *metadata)
1009
9.11k
{
1010
9.11k
    ResultTokenWithMetadata *res = _PyArena_Malloc(p->arena, sizeof(ResultTokenWithMetadata));
1011
9.11k
    if (res == NULL) {
1012
0
        return NULL;
1013
0
    }
1014
9.11k
    res->metadata = metadata;
1015
9.11k
    res->result = result;
1016
9.11k
    return res;
1017
9.11k
}
1018
1019
static char
1020
formatted_string_prefix(const Parser *p)
1021
61
{
1022
61
    int nested = 0;
1023
4.63k
    for (int i = p->mark - 1; i >= 0; i--) {
1024
4.63k
        int type = p->tokens[i]->type;
1025
4.63k
        if (type == FSTRING_END || type == TSTRING_END) {
1026
449
            nested++;
1027
449
        }
1028
4.18k
        else if (type == FSTRING_START || type == TSTRING_START) {
1029
510
            if (nested == 0) {
1030
61
                return type == TSTRING_START ? 't' : 'f';
1031
61
            }
1032
449
            nested--;
1033
449
        }
1034
4.63k
    }
1035
61
    Py_UNREACHABLE();
1036
61
}
1037
1038
ResultTokenWithMetadata *
1039
_PyPegen_check_fstring_conversion(Parser *p, Token* conv_token, expr_ty conv)
1040
2.17k
{
1041
2.17k
    if (conv_token->lineno != conv->lineno || conv_token->end_col_offset != conv->col_offset) {
1042
26
        return RAISE_SYNTAX_ERROR_KNOWN_RANGE(
1043
26
            conv_token, conv,
1044
26
            "%c-string: conversion type must come right after the exclamation mark",
1045
26
            formatted_string_prefix(p)
1046
26
        );
1047
26
    }
1048
1049
2.14k
    Py_UCS4 first = PyUnicode_READ_CHAR(conv->v.Name.id, 0);
1050
2.14k
    if (PyUnicode_GET_LENGTH(conv->v.Name.id) > 1 ||
1051
2.13k
            !(first == 's' || first == 'r' || first == 'a')) {
1052
35
        RAISE_SYNTAX_ERROR_KNOWN_LOCATION(conv,
1053
35
                                            "%c-string: invalid conversion character %R: expected 's', 'r', or 'a'",
1054
35
                                            formatted_string_prefix(p),
1055
35
                                            conv->v.Name.id);
1056
35
        return NULL;
1057
35
    }
1058
1059
2.11k
    return result_token_with_metadata(p, conv, conv_token->metadata);
1060
2.14k
}
1061
1062
ResultTokenWithMetadata *
1063
_PyPegen_setup_full_format_spec(Parser *p, Token *colon, asdl_expr_seq *spec, int lineno, int col_offset,
1064
                                int end_lineno, int end_col_offset, PyArena *arena)
1065
6.99k
{
1066
6.99k
    if (!spec) {
1067
0
        return NULL;
1068
0
    }
1069
1070
    // This is needed to keep compatibility with 3.11, where an empty format
1071
    // spec is parsed as an *empty* JoinedStr node, instead of having an empty
1072
    // constant in it.
1073
6.99k
    Py_ssize_t n_items = asdl_seq_LEN(spec);
1074
6.99k
    Py_ssize_t non_empty_count = 0;
1075
18.7k
    for (Py_ssize_t i = 0; i < n_items; i++) {
1076
11.7k
        expr_ty item = asdl_seq_GET(spec, i);
1077
11.7k
        non_empty_count += !(item->kind == Constant_kind &&
1078
11.7k
                             PyUnicode_CheckExact(item->v.Constant.value) &&
1079
8.06k
                             PyUnicode_GET_LENGTH(item->v.Constant.value) == 0);
1080
11.7k
    }
1081
6.99k
    if (non_empty_count != n_items) {
1082
3.28k
        asdl_expr_seq *resized_spec =
1083
3.28k
            _Py_asdl_expr_seq_new(non_empty_count, p->arena);
1084
3.28k
        if (resized_spec == NULL) {
1085
0
            return NULL;
1086
0
        }
1087
3.28k
        Py_ssize_t j = 0;
1088
8.12k
        for (Py_ssize_t i = 0; i < n_items; i++) {
1089
4.84k
            expr_ty item = asdl_seq_GET(spec, i);
1090
4.84k
            if (item->kind == Constant_kind &&
1091
4.84k
                PyUnicode_CheckExact(item->v.Constant.value) &&
1092
3.87k
                PyUnicode_GET_LENGTH(item->v.Constant.value) == 0) {
1093
3.28k
                continue;
1094
3.28k
            }
1095
1.56k
            asdl_seq_SET(resized_spec, j++, item);
1096
1.56k
        }
1097
3.28k
        assert(j == non_empty_count);
1098
3.28k
        spec = resized_spec;
1099
3.28k
    }
1100
6.99k
    expr_ty res;
1101
6.99k
    Py_ssize_t n = asdl_seq_LEN(spec);
1102
6.99k
    if (n == 0 || (n == 1 && asdl_seq_GET(spec, 0)->kind == Constant_kind)) {
1103
6.31k
        res = _PyAST_JoinedStr(spec, lineno, col_offset, end_lineno,
1104
6.31k
                                    end_col_offset, p->arena);
1105
6.31k
    } else {
1106
685
        res = _PyPegen_concatenate_strings(p, spec,
1107
685
                             lineno, col_offset, end_lineno,
1108
685
                             end_col_offset, arena);
1109
685
    }
1110
6.99k
    if (!res) {
1111
0
        return NULL;
1112
0
    }
1113
6.99k
    return result_token_with_metadata(p, res, colon->metadata);
1114
6.99k
}
1115
1116
const char *
1117
_PyPegen_get_expr_name(expr_ty e)
1118
228
{
1119
228
    assert(e != NULL);
1120
228
    switch (e->kind) {
1121
2
        case Attribute_kind:
1122
2
            return "attribute";
1123
1
        case Subscript_kind:
1124
1
            return "subscript";
1125
2
        case Starred_kind:
1126
2
            return "starred";
1127
9
        case Name_kind:
1128
9
            return "name";
1129
1
        case List_kind:
1130
1
            return "list";
1131
4
        case Tuple_kind:
1132
4
            return "tuple";
1133
2
        case Lambda_kind:
1134
2
            return "lambda";
1135
9
        case Call_kind:
1136
9
            return "function call";
1137
4
        case BoolOp_kind:
1138
38
        case BinOp_kind:
1139
45
        case UnaryOp_kind:
1140
45
            return "expression";
1141
1
        case GeneratorExp_kind:
1142
1
            return "generator expression";
1143
2
        case Yield_kind:
1144
2
        case YieldFrom_kind:
1145
2
            return "yield expression";
1146
1
        case Await_kind:
1147
1
            return "await expression";
1148
1
        case ListComp_kind:
1149
1
            return "list comprehension";
1150
1
        case SetComp_kind:
1151
1
            return "set comprehension";
1152
1
        case DictComp_kind:
1153
1
            return "dict comprehension";
1154
2
        case Dict_kind:
1155
2
            return "dict literal";
1156
3
        case Set_kind:
1157
3
            return "set display";
1158
12
        case JoinedStr_kind:
1159
12
        case FormattedValue_kind:
1160
12
            return "f-string expression";
1161
6
        case TemplateStr_kind:
1162
6
        case Interpolation_kind:
1163
6
            return "t-string expression";
1164
101
        case Constant_kind: {
1165
101
            PyObject *value = e->v.Constant.value;
1166
101
            if (value == Py_None) {
1167
2
                return "None";
1168
2
            }
1169
99
            if (value == Py_False) {
1170
1
                return "False";
1171
1
            }
1172
98
            if (value == Py_True) {
1173
1
                return "True";
1174
1
            }
1175
97
            if (value == Py_Ellipsis) {
1176
1
                return "ellipsis";
1177
1
            }
1178
96
            return "literal";
1179
97
        }
1180
20
        case Compare_kind:
1181
20
            return "comparison";
1182
1
        case IfExp_kind:
1183
1
            return "conditional expression";
1184
1
        case NamedExpr_kind:
1185
1
            return "named expression";
1186
0
        default:
1187
0
            PyErr_Format(PyExc_SystemError,
1188
0
                         "unexpected expression in assignment %d (line %d)",
1189
0
                         e->kind, e->lineno);
1190
0
            return NULL;
1191
228
    }
1192
228
}
1193
1194
expr_ty
1195
16
_PyPegen_get_last_comprehension_item(comprehension_ty comprehension) {
1196
16
    if (comprehension->ifs == NULL || asdl_seq_LEN(comprehension->ifs) == 0) {
1197
12
        return comprehension->iter;
1198
12
    }
1199
4
    return PyPegen_last_item(comprehension->ifs, expr_ty);
1200
16
}
1201
1202
expr_ty _PyPegen_collect_call_seqs(Parser *p, asdl_expr_seq *a, asdl_seq *b,
1203
                     int lineno, int col_offset, int end_lineno,
1204
27.8k
                     int end_col_offset, PyArena *arena) {
1205
27.8k
    Py_ssize_t args_len = asdl_seq_LEN(a);
1206
27.8k
    Py_ssize_t total_len = args_len;
1207
1208
27.8k
    if (b == NULL) {
1209
25.6k
        return _PyAST_Call(_PyPegen_dummy_name(p), a, NULL, lineno, col_offset,
1210
25.6k
                        end_lineno, end_col_offset, arena);
1211
1212
25.6k
    }
1213
1214
2.16k
    asdl_expr_seq *starreds = _PyPegen_seq_extract_starred_exprs(p, b);
1215
2.16k
    if (!starreds && PyErr_Occurred()) {
1216
0
        return NULL;
1217
0
    }
1218
1219
2.16k
    asdl_keyword_seq *keywords = _PyPegen_seq_delete_starred_exprs(p, b);
1220
2.16k
    if (!keywords && PyErr_Occurred()) {
1221
0
        return NULL;
1222
0
    }
1223
1224
2.16k
    if (starreds) {
1225
295
        total_len += asdl_seq_LEN(starreds);
1226
295
    }
1227
1228
2.16k
    asdl_expr_seq *args = _Py_asdl_expr_seq_new(total_len, arena);
1229
2.16k
    if (args == NULL) {
1230
0
        return NULL;
1231
0
    }
1232
1233
2.16k
    Py_ssize_t i = 0;
1234
4.73k
    for (i = 0; i < args_len; i++) {
1235
2.57k
        asdl_seq_SET(args, i, asdl_seq_GET(a, i));
1236
2.57k
    }
1237
2.78k
    for (; i < total_len; i++) {
1238
623
        asdl_seq_SET(args, i, asdl_seq_GET(starreds, i - args_len));
1239
623
    }
1240
1241
2.16k
    return _PyAST_Call(_PyPegen_dummy_name(p), args, keywords, lineno,
1242
2.16k
                       col_offset, end_lineno, end_col_offset, arena);
1243
2.16k
}
1244
1245
// AST Error reporting helpers
1246
1247
expr_ty
1248
_PyPegen_get_invalid_target(expr_ty e, TARGETS_TYPE targets_type)
1249
374k
{
1250
374k
    if (e == NULL) {
1251
0
        return NULL;
1252
0
    }
1253
1254
374k
    if (targets_type == SINGLE_TARGETS ||
1255
260k
        targets_type == ATTRIBUTE_OR_SUBSCRIPT_TARGETS) {
1256
231k
        if (targets_type == SINGLE_TARGETS && e->kind == Name_kind) {
1257
73.5k
            return NULL;
1258
73.5k
        }
1259
157k
        return e->kind == Attribute_kind || e->kind == Subscript_kind ? NULL : e;
1260
231k
    }
1261
1262
143k
#define VISIT_CONTAINER(CONTAINER, TYPE) do { \
1263
7.38k
        Py_ssize_t len = asdl_seq_LEN((CONTAINER)->v.TYPE.elts);\
1264
11.9k
        for (Py_ssize_t i = 0; i < len; i++) {\
1265
5.13k
            expr_ty other = asdl_seq_GET((CONTAINER)->v.TYPE.elts, i);\
1266
5.13k
            expr_ty child = _PyPegen_get_invalid_target(other, targets_type);\
1267
5.13k
            if (child != NULL) {\
1268
589
                return child;\
1269
589
            }\
1270
5.13k
        }\
1271
7.38k
    } while (0)
1272
1273
    // We only need to visit List and Tuple nodes recursively as those
1274
    // are the only ones that can contain valid names in targets when
1275
    // they are parsed as expressions. Any other kind of expression
1276
    // that is a container (like Sets or Dicts) is directly invalid and
1277
    // we don't need to visit it recursively.
1278
1279
143k
    switch (e->kind) {
1280
1.79k
        case List_kind:
1281
1.79k
            VISIT_CONTAINER(e, List);
1282
1.51k
            return NULL;
1283
5.58k
        case Tuple_kind:
1284
5.58k
            VISIT_CONTAINER(e, Tuple);
1285
5.28k
            return NULL;
1286
1.03k
        case Starred_kind:
1287
1.03k
            if (targets_type == DEL_TARGETS) {
1288
6
                return e;
1289
6
            }
1290
1.02k
            return _PyPegen_get_invalid_target(e->v.Starred.value, targets_type);
1291
977
        case Compare_kind:
1292
            // This is needed, because the `a in b` in `for a in b` gets parsed
1293
            // as a comparison, and so we need to search the left side of the comparison
1294
            // for invalid targets.
1295
977
            if (targets_type == FOR_TARGETS) {
1296
848
                cmpop_ty cmpop = (cmpop_ty) asdl_seq_GET(e->v.Compare.ops, 0);
1297
848
                if (cmpop == In) {
1298
262
                    return _PyPegen_get_invalid_target(e->v.Compare.left, targets_type);
1299
262
                }
1300
586
                return NULL;
1301
848
            }
1302
129
            return e;
1303
92.1k
        case Name_kind:
1304
93.2k
        case Subscript_kind:
1305
95.3k
        case Attribute_kind:
1306
95.3k
            return NULL;
1307
38.9k
        default:
1308
38.9k
            return e;
1309
143k
    }
1310
143k
}
1311
1312
31
void *_PyPegen_arguments_parsing_error(Parser *p, expr_ty e) {
1313
31
    int kwarg_unpacking = 0;
1314
892
    for (Py_ssize_t i = 0, l = asdl_seq_LEN(e->v.Call.keywords); i < l; i++) {
1315
861
        keyword_ty keyword = asdl_seq_GET(e->v.Call.keywords, i);
1316
861
        if (!keyword->arg) {
1317
536
            kwarg_unpacking = 1;
1318
536
        }
1319
861
    }
1320
1321
31
    const char *msg = NULL;
1322
31
    if (kwarg_unpacking) {
1323
17
        msg = "positional argument follows keyword argument unpacking";
1324
17
    } else {
1325
14
        msg = "positional argument follows keyword argument";
1326
14
    }
1327
1328
31
    return RAISE_SYNTAX_ERROR(msg);
1329
31
}
1330
1331
void *
1332
_PyPegen_nonparen_genexp_in_call(Parser *p, expr_ty args, asdl_comprehension_seq *comprehensions)
1333
261
{
1334
    /* The rule that calls this function is 'args for_if_clauses'.
1335
       For the input f(L, x for x in y), L and x are in args and
1336
       the for is parsed as a for_if_clause. We have to check if
1337
       len <= 1, so that input like dict((a, b) for a, b in x)
1338
       gets successfully parsed and then we pass the last
1339
       argument (x in the above example) as the location of the
1340
       error */
1341
261
    Py_ssize_t len = asdl_seq_LEN(args->v.Call.args);
1342
261
    if (len <= 1) {
1343
259
        return NULL;
1344
259
    }
1345
1346
2
    comprehension_ty last_comprehension = PyPegen_last_item(comprehensions, comprehension_ty);
1347
1348
2
    return RAISE_SYNTAX_ERROR_KNOWN_RANGE(
1349
261
        (expr_ty) asdl_seq_GET(args->v.Call.args, len - 1),
1350
261
        _PyPegen_get_last_comprehension_item(last_comprehension),
1351
261
        "Generator expression must be parenthesized"
1352
261
    );
1353
261
}
1354
1355
// Fstring stuff
1356
1357
static expr_ty
1358
30.4k
_PyPegen_decode_fstring_part(Parser* p, int is_raw, expr_ty constant, Token* token) {
1359
30.4k
    assert(PyUnicode_CheckExact(constant->v.Constant.value));
1360
1361
30.4k
    const char* bstr = PyUnicode_AsUTF8(constant->v.Constant.value);
1362
30.4k
    if (bstr == NULL) {
1363
0
        return NULL;
1364
0
    }
1365
1366
30.4k
    size_t len;
1367
30.4k
    if (strcmp(bstr, "{{") == 0 || strcmp(bstr, "}}") == 0) {
1368
0
        len = 1;
1369
30.4k
    } else {
1370
30.4k
        len = strlen(bstr);
1371
30.4k
    }
1372
1373
30.4k
    is_raw = is_raw || strchr(bstr, '\\') == NULL;
1374
30.4k
    PyObject *str = _PyPegen_decode_string(p, is_raw, bstr, len, token);
1375
30.4k
    if (str == NULL) {
1376
9
        _Pypegen_raise_decode_error_known_location(p, constant);
1377
9
        return NULL;
1378
9
    }
1379
30.4k
    if (_PyArena_AddPyObject(p->arena, str) < 0) {
1380
0
        Py_DECREF(str);
1381
0
        return NULL;
1382
0
    }
1383
30.4k
    return _PyAST_Constant(str, NULL, constant->lineno, constant->col_offset,
1384
30.4k
                           constant->end_lineno, constant->end_col_offset,
1385
30.4k
                           p->arena);
1386
30.4k
}
1387
1388
static asdl_expr_seq *
1389
_get_resized_exprs(Parser *p, Token *a, asdl_expr_seq *raw_expressions,
1390
                   Token *b, int is_tstring)
1391
19.7k
{
1392
19.7k
    Py_ssize_t n_items = asdl_seq_LEN(raw_expressions);
1393
19.7k
    Py_ssize_t total_items = n_items;
1394
72.0k
    for (Py_ssize_t i = 0; i < n_items; i++) {
1395
52.2k
        expr_ty item = asdl_seq_GET(raw_expressions, i);
1396
52.2k
        if (item->kind == JoinedStr_kind) {
1397
7.18k
            total_items += asdl_seq_LEN(item->v.JoinedStr.values) - 1;
1398
7.18k
        }
1399
52.2k
    }
1400
1401
19.7k
    const char* quote_str = PyBytes_AsString(a->bytes);
1402
19.7k
    if (quote_str == NULL) {
1403
0
        return NULL;
1404
0
    }
1405
19.7k
    int is_raw = strpbrk(quote_str, "rR") != NULL;
1406
1407
19.7k
    asdl_expr_seq *seq = _Py_asdl_expr_seq_new(total_items, p->arena);
1408
19.7k
    if (seq == NULL) {
1409
0
        return NULL;
1410
0
    }
1411
1412
19.7k
    Py_ssize_t index = 0;
1413
72.0k
    for (Py_ssize_t i = 0; i < n_items; i++) {
1414
52.2k
        expr_ty item = asdl_seq_GET(raw_expressions, i);
1415
1416
        /* Debug expressions arrive as JoinedStr(text, value); flatten them
1417
           into the surrounding string. */
1418
52.2k
        if (item->kind == JoinedStr_kind) {
1419
7.18k
            asdl_expr_seq *values = item->v.JoinedStr.values;
1420
7.18k
            if (asdl_seq_LEN(values) != 2) {
1421
0
                PyErr_Format(PyExc_SystemError,
1422
0
                             is_tstring
1423
0
                             ? "unexpected TemplateStr node without debug data in t-string at line %d"
1424
0
                             : "unexpected JoinedStr node without debug data in f-string at line %d",
1425
0
                             item->lineno);
1426
0
                return NULL;
1427
0
            }
1428
1429
7.18k
            expr_ty first = asdl_seq_GET(values, 0);
1430
7.18k
            assert(first->kind == Constant_kind);
1431
7.18k
            asdl_seq_SET(seq, index++, first);
1432
1433
7.18k
            expr_ty second = asdl_seq_GET(values, 1);
1434
7.18k
            assert((is_tstring &&
1435
7.18k
                    second->kind == Interpolation_kind) ||
1436
7.18k
                   second->kind == FormattedValue_kind);
1437
7.18k
            asdl_seq_SET(seq, index++, second);
1438
1439
7.18k
            continue;
1440
7.18k
        }
1441
1442
45.1k
        if (item->kind == Constant_kind) {
1443
30.4k
            item = _PyPegen_decode_fstring_part(p, is_raw, item, b);
1444
30.4k
            if (item == NULL) {
1445
9
                return NULL;
1446
9
            }
1447
1448
            /* Tokenizer emits string parts even when the underlying string
1449
            might become an empty value (e.g. FSTRING_MIDDLE with the value \\n)
1450
            so we need to check for them and simplify it here. */
1451
30.4k
            if (PyUnicode_CheckExact(item->v.Constant.value)
1452
30.4k
                && PyUnicode_GET_LENGTH(item->v.Constant.value) == 0) {
1453
629
                continue;
1454
629
            }
1455
30.4k
        }
1456
44.4k
        asdl_seq_SET(seq, index++, item);
1457
44.4k
    }
1458
1459
19.7k
    asdl_expr_seq *resized_exprs;
1460
19.7k
    if (index != total_items) {
1461
629
        resized_exprs = _Py_asdl_expr_seq_new(index, p->arena);
1462
629
        if (resized_exprs == NULL) {
1463
0
            return NULL;
1464
0
        }
1465
2.60k
        for (Py_ssize_t i = 0; i < index; i++) {
1466
1.97k
            asdl_seq_SET(resized_exprs, i, asdl_seq_GET(seq, i));
1467
1.97k
        }
1468
629
    }
1469
19.1k
    else {
1470
19.1k
        resized_exprs = seq;
1471
19.1k
    }
1472
19.7k
    return resized_exprs;
1473
19.7k
}
1474
1475
expr_ty
1476
3.44k
_PyPegen_template_str(Parser *p, Token *a, asdl_expr_seq *raw_expressions, Token *b) {
1477
1478
3.44k
    asdl_expr_seq *resized_exprs = _get_resized_exprs(p, a, raw_expressions, b, 1);
1479
3.44k
    if (resized_exprs == NULL) {
1480
5
        return NULL;
1481
5
    }
1482
3.43k
    return _PyAST_TemplateStr(resized_exprs, a->lineno, a->col_offset,
1483
3.43k
                              b->end_lineno, b->end_col_offset,
1484
3.43k
                              p->arena);
1485
3.44k
}
1486
1487
expr_ty
1488
16.3k
_PyPegen_joined_str(Parser *p, Token* a, asdl_expr_seq* raw_expressions, Token*b) {
1489
1490
16.3k
    asdl_expr_seq *resized_exprs = _get_resized_exprs(p, a, raw_expressions, b, 0);
1491
16.3k
    if (resized_exprs == NULL) {
1492
4
        return NULL;
1493
4
    }
1494
16.3k
    return _PyAST_JoinedStr(resized_exprs, a->lineno, a->col_offset,
1495
16.3k
                            b->end_lineno, b->end_col_offset,
1496
16.3k
                            p->arena);
1497
16.3k
}
1498
1499
8.44k
expr_ty _PyPegen_decoded_constant_from_token(Parser* p, Token* tok) {
1500
8.44k
    if (tok->bytes == NULL) {
1501
0
        return _PyPegen_raise_incomplete_input(p);
1502
0
    }
1503
8.44k
    Py_ssize_t bsize = PyBytes_GET_SIZE(tok->bytes);
1504
8.44k
    const char *bstr = PyBytes_AS_STRING(tok->bytes);
1505
1506
8.44k
    int is_raw = tok->is_raw;
1507
1508
8.44k
    PyObject* str = _PyPegen_decode_string(p, is_raw, bstr, bsize, tok);
1509
8.44k
    if (str == NULL) {
1510
4
        if ((p->flags & PyPARSE_ALLOW_INCOMPLETE_INPUT) || tok->is_incomplete) {
1511
0
            _Pypegen_raise_decode_error(p);
1512
0
        }
1513
4
        return NULL;
1514
4
    }
1515
8.43k
    if (tok->is_incomplete) {
1516
0
        Py_DECREF(str);
1517
0
        return _PyPegen_raise_incomplete_input(p);
1518
0
    }
1519
8.43k
    if (_PyArena_AddPyObject(p->arena, str) < 0) {
1520
0
        Py_DECREF(str);
1521
0
        return NULL;
1522
0
    }
1523
8.43k
    return _PyAST_Constant(str, NULL, tok->lineno, tok->col_offset,
1524
8.43k
                           tok->end_lineno, tok->end_col_offset,
1525
8.43k
                           p->arena);
1526
8.43k
}
1527
1528
34.4k
expr_ty _PyPegen_constant_from_token(Parser* p, Token* tok) {
1529
34.4k
    if (tok->bytes == NULL) {
1530
0
        return _PyPegen_raise_incomplete_input(p);
1531
0
    }
1532
34.4k
    const char *bstr = PyBytes_AS_STRING(tok->bytes);
1533
34.4k
    Py_ssize_t bsize = PyBytes_GET_SIZE(tok->bytes);
1534
34.4k
    if (((p->flags & PyPARSE_ALLOW_INCOMPLETE_INPUT) || tok->is_incomplete) &&
1535
0
        !tok->is_raw && memchr(bstr, '\\', bsize) != NULL) {
1536
        // Check escapes before the string is complete, without emitting warnings.
1537
0
        PyObject *decoded = _PyPegen_decode_string(
1538
0
            p, 0, bstr, bsize, tok->is_incomplete ? tok : NULL);
1539
0
        if (decoded == NULL) {
1540
0
            _Pypegen_raise_decode_error(p);
1541
0
            return NULL;
1542
0
        }
1543
0
        Py_DECREF(decoded);
1544
0
    }
1545
34.4k
    if (tok->is_incomplete) {
1546
0
        return _PyPegen_raise_incomplete_input(p);
1547
0
    }
1548
34.4k
    PyObject* str = PyUnicode_FromString(bstr);
1549
34.4k
    if (str == NULL) {
1550
0
        return NULL;
1551
0
    }
1552
34.4k
    if (_PyArena_AddPyObject(p->arena, str) < 0) {
1553
0
        Py_DECREF(str);
1554
0
        return NULL;
1555
0
    }
1556
34.4k
    return _PyAST_Constant(str, NULL, tok->lineno, tok->col_offset,
1557
34.4k
                           tok->end_lineno, tok->end_col_offset,
1558
34.4k
                           p->arena);
1559
34.4k
}
1560
1561
54.9k
expr_ty _PyPegen_constant_from_string(Parser* p, Token* tok) {
1562
54.9k
    if (tok->bytes == NULL) {
1563
0
        return _PyPegen_raise_incomplete_input(p);
1564
0
    }
1565
54.9k
    const char *the_str = PyBytes_AS_STRING(tok->bytes);
1566
54.9k
    PyObject *s = _PyPegen_parse_string(p, tok);
1567
54.9k
    if (s == NULL) {
1568
120
        _Pypegen_raise_decode_error(p);
1569
120
        return NULL;
1570
120
    }
1571
54.7k
    if (_PyArena_AddPyObject(p->arena, s) < 0) {
1572
0
        Py_DECREF(s);
1573
0
        return NULL;
1574
0
    }
1575
54.7k
    PyObject *kind = NULL;
1576
54.7k
    if (the_str && the_str[0] == 'u') {
1577
3.81k
        kind = _PyPegen_new_identifier(p, "u");
1578
3.81k
        if (kind == NULL) {
1579
0
            return NULL;
1580
0
        }
1581
3.81k
    }
1582
54.7k
    return _PyAST_Constant(s, kind, tok->lineno, tok->col_offset, tok->end_lineno, tok->end_col_offset, p->arena);
1583
54.7k
}
1584
1585
static int
1586
_get_interpolation_conversion(Parser *p, Token *debug, ResultTokenWithMetadata *conversion,
1587
                              ResultTokenWithMetadata *format)
1588
29.2k
{
1589
29.2k
    if (conversion != NULL) {
1590
2.08k
        expr_ty conversion_expr = (expr_ty) conversion->result;
1591
2.08k
        assert(conversion_expr->kind == Name_kind);
1592
2.08k
        Py_UCS4 first = PyUnicode_READ_CHAR(conversion_expr->v.Name.id, 0);
1593
2.08k
        return Py_SAFE_DOWNCAST(first, Py_UCS4, int);
1594
2.08k
    }
1595
27.1k
    else if (debug && !format) {
1596
        /* If no conversion is specified, use !r for debug expressions */
1597
7.89k
        return (int)'r';
1598
7.89k
    }
1599
19.2k
    return -1;
1600
29.2k
}
1601
1602
static PyObject *
1603
_strip_interpolation_debug_expr(PyObject *exprstr)
1604
1.76k
{
1605
1.76k
    Py_ssize_t len = PyUnicode_GET_LENGTH(exprstr);
1606
1607
    /* Discard whitespace and explicit line continuations after the debug "="
1608
       but preserve whitespace before it. */
1609
2.20k
    while (len > 0) {
1610
2.20k
        int has_newline = 0;
1611
5.11k
        while (len > 0) {
1612
5.11k
            Py_UCS4 c = PyUnicode_READ_CHAR(exprstr, len - 1);
1613
5.11k
            if (!_PyUnicode_IsWhitespace(c)) {
1614
2.20k
                break;
1615
2.20k
            }
1616
2.91k
            if (c == '\r' || c == '\n') {
1617
1.83k
                has_newline = 1;
1618
1.83k
            }
1619
2.91k
            len--;
1620
2.91k
        }
1621
2.20k
        if (!has_newline || len == 0 ||
1622
849
            PyUnicode_READ_CHAR(exprstr, len - 1) != '\\')
1623
1.76k
        {
1624
1.76k
            break;
1625
1.76k
        }
1626
438
        len--;
1627
438
    }
1628
1629
    /* Preserve unexpected metadata instead of dropping source text. */
1630
1.76k
    if (len == 0 || PyUnicode_READ_CHAR(exprstr, len - 1) != '=') {
1631
0
        return Py_NewRef(exprstr);
1632
0
    }
1633
1634
1.76k
    return PyUnicode_Substring(exprstr, 0, len - 1);
1635
1.76k
}
1636
1637
expr_ty _PyPegen_interpolation(Parser *p, expr_ty expression, Token *debug, ResultTokenWithMetadata *conversion,
1638
                                 ResultTokenWithMetadata *format, Token *closing_brace, int lineno, int col_offset,
1639
7.57k
                                 int end_lineno, int end_col_offset, PyArena *arena) {
1640
1641
7.57k
    int conversion_val = _get_interpolation_conversion(p, debug, conversion, format);
1642
1643
    /* Find the non whitespace token after the "=" */
1644
7.57k
    int debug_end_line, debug_end_offset;
1645
7.57k
    PyObject *debug_metadata;
1646
7.57k
    constant exprstr;
1647
1648
7.57k
    if (conversion) {
1649
265
        debug_end_line = ((expr_ty) conversion->result)->lineno;
1650
265
        debug_end_offset = ((expr_ty) conversion->result)->col_offset;
1651
265
        debug_metadata = exprstr = conversion->metadata;
1652
265
    }
1653
7.30k
    else if (format) {
1654
1.39k
        debug_end_line = ((expr_ty) format->result)->lineno;
1655
1.39k
        debug_end_offset = ((expr_ty) format->result)->col_offset + 1;
1656
1.39k
        debug_metadata = exprstr = format->metadata;
1657
1.39k
    }
1658
5.90k
    else {
1659
5.90k
        debug_end_line = end_lineno;
1660
5.90k
        debug_end_offset = end_col_offset;
1661
5.90k
        debug_metadata = exprstr = closing_brace->metadata;
1662
5.90k
    }
1663
1664
7.57k
    assert(exprstr != NULL);
1665
7.57k
    PyObject *final_exprstr = debug
1666
7.57k
        ? _strip_interpolation_debug_expr(exprstr)
1667
7.57k
        : Py_NewRef(exprstr);
1668
7.57k
    if (!final_exprstr || _PyArena_AddPyObject(arena, final_exprstr) < 0) {
1669
0
        Py_XDECREF(final_exprstr);
1670
0
        return NULL;
1671
0
    }
1672
1673
7.57k
    expr_ty interpolation = _PyAST_Interpolation(
1674
7.57k
        expression, final_exprstr, conversion_val, format ? (expr_ty) format->result : NULL,
1675
7.57k
        lineno, col_offset, end_lineno,
1676
7.57k
        end_col_offset, arena
1677
7.57k
    );
1678
1679
7.57k
    if (!interpolation || !debug) {
1680
5.80k
        return interpolation;
1681
5.80k
    }
1682
1683
1.76k
    expr_ty debug_text = _PyAST_Constant(debug_metadata, NULL, lineno, col_offset + 1, debug_end_line,
1684
1.76k
                                            debug_end_offset - 1, p->arena);
1685
1.76k
    if (!debug_text) {
1686
0
        return NULL;
1687
0
    }
1688
1689
1.76k
    asdl_expr_seq *values = _Py_asdl_expr_seq_new(2, arena);
1690
1.76k
    if (!values) {
1691
0
        return NULL;
1692
0
    }
1693
1.76k
    asdl_seq_SET(values, 0, debug_text);
1694
1.76k
    asdl_seq_SET(values, 1, interpolation);
1695
1.76k
    return _PyAST_JoinedStr(values, lineno, col_offset, debug_end_line, debug_end_offset, p->arena);
1696
1.76k
}
1697
1698
expr_ty _PyPegen_formatted_value(Parser *p, expr_ty expression, Token *debug, ResultTokenWithMetadata *conversion,
1699
                                 ResultTokenWithMetadata *format, Token *closing_brace, int lineno, int col_offset,
1700
21.7k
                                 int end_lineno, int end_col_offset, PyArena *arena) {
1701
21.7k
    int conversion_val = _get_interpolation_conversion(p, debug, conversion, format);
1702
1703
21.7k
    expr_ty formatted_value = _PyAST_FormattedValue(
1704
21.7k
        expression, conversion_val, format ? (expr_ty) format->result : NULL,
1705
21.7k
        lineno, col_offset, end_lineno,
1706
21.7k
        end_col_offset, arena
1707
21.7k
    );
1708
1709
21.7k
    if (!formatted_value || !debug) {
1710
14.5k
        return formatted_value;
1711
14.5k
    }
1712
1713
    /* Find the non whitespace token after the "=" */
1714
7.19k
    int debug_end_line, debug_end_offset;
1715
7.19k
    PyObject *debug_metadata;
1716
1717
7.19k
    if (conversion) {
1718
199
        debug_end_line = ((expr_ty) conversion->result)->lineno;
1719
199
        debug_end_offset = ((expr_ty) conversion->result)->col_offset;
1720
199
        debug_metadata = conversion->metadata;
1721
199
    }
1722
7.00k
    else if (format) {
1723
257
        debug_end_line = ((expr_ty) format->result)->lineno;
1724
257
        debug_end_offset = ((expr_ty) format->result)->col_offset + 1;
1725
257
        debug_metadata = format->metadata;
1726
257
    }
1727
6.74k
    else {
1728
6.74k
        debug_end_line = end_lineno;
1729
6.74k
        debug_end_offset = end_col_offset;
1730
6.74k
        debug_metadata = closing_brace->metadata;
1731
6.74k
    }
1732
7.19k
    expr_ty debug_text = _PyAST_Constant(debug_metadata, NULL, lineno, col_offset + 1, debug_end_line,
1733
7.19k
                                            debug_end_offset - 1, p->arena);
1734
7.19k
    if (!debug_text) {
1735
0
        return NULL;
1736
0
    }
1737
1738
7.19k
    asdl_expr_seq *values = _Py_asdl_expr_seq_new(2, arena);
1739
7.19k
    if (!values) {
1740
0
        return NULL;
1741
0
    }
1742
7.19k
    asdl_seq_SET(values, 0, debug_text);
1743
7.19k
    asdl_seq_SET(values, 1, formatted_value);
1744
7.19k
    return _PyAST_JoinedStr(values, lineno, col_offset, debug_end_line, debug_end_offset, p->arena);
1745
7.19k
}
1746
1747
static expr_ty
1748
_build_concatenated_bytes(Parser *p, asdl_expr_seq *strings, int lineno,
1749
                        int col_offset, int end_lineno, int end_col_offset,
1750
                        PyArena *arena)
1751
776
{
1752
776
    Py_ssize_t len = asdl_seq_LEN(strings);
1753
776
    assert(len > 0);
1754
1755
    /* Bytes literals never get a kind, but just for consistency
1756
        since they are represented as Constant nodes, we'll mirror
1757
        the same behavior as unicode strings for determining the
1758
        kind. */
1759
776
    PyObject *kind = asdl_seq_GET(strings, 0)->v.Constant.kind;
1760
1761
776
    Py_ssize_t total = 0;
1762
3.56k
    for (Py_ssize_t i = 0; i < len; i++) {
1763
2.78k
        expr_ty elem = asdl_seq_GET(strings, i);
1764
2.78k
        PyObject *bytes = elem->v.Constant.value;
1765
2.78k
        Py_ssize_t part = PyBytes_GET_SIZE(bytes);
1766
2.78k
        if (part > PY_SSIZE_T_MAX - total) {
1767
0
            PyErr_NoMemory();
1768
0
            return NULL;
1769
0
        }
1770
2.78k
        total += part;
1771
2.78k
    }
1772
1773
776
    PyBytesWriter *writer = PyBytesWriter_Create(total);
1774
776
    if (writer == NULL) {
1775
0
        return NULL;
1776
0
    }
1777
776
    char *out = PyBytesWriter_GetData(writer);
1778
1779
3.56k
    for (Py_ssize_t i = 0; i < len; i++) {
1780
2.78k
        expr_ty elem = asdl_seq_GET(strings, i);
1781
2.78k
        PyObject *bytes = elem->v.Constant.value;
1782
2.78k
        Py_ssize_t part = PyBytes_GET_SIZE(bytes);
1783
2.78k
        if (part > 0) {
1784
1.13k
            memcpy(out, PyBytes_AS_STRING(bytes), part);
1785
1.13k
            out += part;
1786
1.13k
        }
1787
2.78k
    }
1788
1789
776
    PyObject *res = PyBytesWriter_Finish(writer);
1790
776
    if (res == NULL) {
1791
0
        return NULL;
1792
0
    }
1793
776
    if (_PyArena_AddPyObject(arena, res) < 0) {
1794
0
        Py_DECREF(res);
1795
0
        return NULL;
1796
0
    }
1797
776
    return _PyAST_Constant(res, kind, lineno, col_offset, end_lineno, end_col_offset, p->arena);
1798
776
}
1799
1800
static expr_ty
1801
_build_concatenated_unicode(Parser *p, asdl_expr_seq *strings, int lineno,
1802
                        int col_offset, int end_lineno, int end_col_offset,
1803
                        PyArena *arena)
1804
1.97k
{
1805
1.97k
    Py_ssize_t len = asdl_seq_LEN(strings);
1806
1.97k
    assert(len > 1);
1807
1808
1.97k
    expr_ty first = asdl_seq_GET(strings, 0);
1809
1810
    /* When a string is getting concatenated, the kind of the string
1811
        is determined by the first string in the concatenation
1812
        sequence.
1813
1814
        u"abc" "def" -> u"abcdef"
1815
        "abc" u"abc" ->  "abcabc" */
1816
1.97k
    PyObject *kind = first->v.Constant.kind;
1817
1818
1.97k
    PyUnicodeWriter *writer = PyUnicodeWriter_Create(0);
1819
1.97k
    if (writer == NULL) {
1820
0
        return NULL;
1821
0
    }
1822
1823
25.5k
    for (Py_ssize_t i = 0; i < len; i++) {
1824
23.5k
        expr_ty current_elem = asdl_seq_GET(strings, i);
1825
23.5k
        assert(current_elem->kind == Constant_kind);
1826
1827
23.5k
        if (PyUnicodeWriter_WriteStr(writer,
1828
23.5k
                                     current_elem->v.Constant.value)) {
1829
0
            PyUnicodeWriter_Discard(writer);
1830
0
            return NULL;
1831
0
        }
1832
23.5k
    }
1833
1834
1.97k
    PyObject *final = PyUnicodeWriter_Finish(writer);
1835
1.97k
    if (final == NULL) {
1836
0
        return NULL;
1837
0
    }
1838
1.97k
    if (_PyArena_AddPyObject(p->arena, final) < 0) {
1839
0
        Py_DECREF(final);
1840
0
        return NULL;
1841
0
    }
1842
1.97k
    return _PyAST_Constant(final, kind, lineno, col_offset,
1843
1.97k
                           end_lineno, end_col_offset, arena);
1844
1.97k
}
1845
1846
static asdl_expr_seq *
1847
_build_concatenated_str(Parser *p, asdl_expr_seq *strings,
1848
                               int lineno, int col_offset, int end_lineno,
1849
                               int end_col_offset, PyArena *arena)
1850
12.6k
{
1851
12.6k
    Py_ssize_t len = asdl_seq_LEN(strings);
1852
12.6k
    assert(len > 0);
1853
1854
12.6k
    Py_ssize_t n_flattened_elements = 0;
1855
39.5k
    for (Py_ssize_t i = 0; i < len; i++) {
1856
26.8k
        expr_ty elem = asdl_seq_GET(strings, i);
1857
26.8k
        switch(elem->kind) {
1858
13.6k
            case JoinedStr_kind:
1859
13.6k
                n_flattened_elements += asdl_seq_LEN(elem->v.JoinedStr.values);
1860
13.6k
                break;
1861
2.90k
            case TemplateStr_kind:
1862
2.90k
                n_flattened_elements += asdl_seq_LEN(elem->v.TemplateStr.values);
1863
2.90k
                break;
1864
10.3k
            default:
1865
10.3k
                n_flattened_elements++;
1866
10.3k
                break;
1867
26.8k
        }
1868
26.8k
    }
1869
1870
1871
12.6k
    asdl_expr_seq* flattened = _Py_asdl_expr_seq_new(n_flattened_elements, p->arena);
1872
12.6k
    if (flattened == NULL) {
1873
0
        return NULL;
1874
0
    }
1875
1876
    /* build flattened list */
1877
12.6k
    Py_ssize_t current_pos = 0;
1878
39.5k
    for (Py_ssize_t i = 0; i < len; i++) {
1879
26.8k
        expr_ty elem = asdl_seq_GET(strings, i);
1880
26.8k
        switch(elem->kind) {
1881
13.6k
            case JoinedStr_kind:
1882
55.7k
                for (Py_ssize_t j = 0; j < asdl_seq_LEN(elem->v.JoinedStr.values); j++) {
1883
42.0k
                    expr_ty subvalue = asdl_seq_GET(elem->v.JoinedStr.values, j);
1884
42.0k
                    if (subvalue == NULL) {
1885
0
                        return NULL;
1886
0
                    }
1887
42.0k
                    asdl_seq_SET(flattened, current_pos++, subvalue);
1888
42.0k
                }
1889
13.6k
                break;
1890
13.6k
            case TemplateStr_kind:
1891
14.4k
                for (Py_ssize_t j = 0; j < asdl_seq_LEN(elem->v.TemplateStr.values); j++) {
1892
11.5k
                    expr_ty subvalue = asdl_seq_GET(elem->v.TemplateStr.values, j);
1893
11.5k
                    if (subvalue == NULL) {
1894
0
                        return NULL;
1895
0
                    }
1896
11.5k
                    asdl_seq_SET(flattened, current_pos++, subvalue);
1897
11.5k
                }
1898
2.90k
                break;
1899
10.3k
            default:
1900
10.3k
                asdl_seq_SET(flattened, current_pos++, elem);
1901
10.3k
                break;
1902
26.8k
        }
1903
26.8k
    }
1904
1905
    /* calculate folded element count */
1906
12.6k
    Py_ssize_t n_elements = 0;
1907
12.6k
    int prev_is_constant = 0;
1908
76.5k
    for (Py_ssize_t i = 0; i < n_flattened_elements; i++) {
1909
63.8k
        expr_ty elem = asdl_seq_GET(flattened, i);
1910
1911
        /* The concatenation of a FormattedValue and an empty Constant should
1912
           lead to the FormattedValue itself. Thus, we will not take any empty
1913
           constants into account, just as in `_PyPegen_joined_str` */
1914
63.8k
        if (elem->kind == Constant_kind &&
1915
63.8k
            PyUnicode_CheckExact(elem->v.Constant.value) &&
1916
39.5k
            PyUnicode_GET_LENGTH(elem->v.Constant.value) == 0)
1917
1.70k
            continue;
1918
1919
62.1k
        if (!prev_is_constant || elem->kind != Constant_kind) {
1920
50.6k
            n_elements++;
1921
50.6k
        }
1922
62.1k
        prev_is_constant = elem->kind == Constant_kind;
1923
62.1k
    }
1924
1925
12.6k
    asdl_expr_seq* values = _Py_asdl_expr_seq_new(n_elements, p->arena);
1926
12.6k
    if (values == NULL) {
1927
0
        return NULL;
1928
0
    }
1929
1930
    /* build folded list */
1931
12.6k
    current_pos = 0;
1932
63.6k
    for (Py_ssize_t i = 0; i < n_flattened_elements; i++) {
1933
50.9k
        expr_ty elem = asdl_seq_GET(flattened, i);
1934
1935
        /* if the current elem and the following are constants,
1936
           fold them and all consequent constants */
1937
50.9k
        if (elem->kind == Constant_kind) {
1938
26.6k
            if (i + 1 < n_flattened_elements &&
1939
22.7k
                asdl_seq_GET(flattened, i + 1)->kind == Constant_kind) {
1940
3.82k
                expr_ty first_elem = elem;
1941
1942
                /* When a string is getting concatenated, the kind of the string
1943
                   is determined by the first string in the concatenation
1944
                   sequence.
1945
1946
                   u"abc" "def" -> u"abcdef"
1947
                   "abc" u"abc" ->  "abcabc" */
1948
3.82k
                PyObject *kind = elem->v.Constant.kind;
1949
1950
3.82k
                PyUnicodeWriter *writer = PyUnicodeWriter_Create(0);
1951
3.82k
                if (writer == NULL) {
1952
0
                    return NULL;
1953
0
                }
1954
3.82k
                expr_ty last_elem = elem;
1955
3.82k
                Py_ssize_t j;
1956
20.5k
                for (j = i; j < n_flattened_elements; j++) {
1957
18.6k
                    expr_ty current_elem = asdl_seq_GET(flattened, j);
1958
18.6k
                    if (current_elem->kind == Constant_kind) {
1959
16.7k
                        if (PyUnicodeWriter_WriteStr(writer,
1960
16.7k
                                                     current_elem->v.Constant.value)) {
1961
0
                            PyUnicodeWriter_Discard(writer);
1962
0
                            return NULL;
1963
0
                        }
1964
16.7k
                        last_elem = current_elem;
1965
16.7k
                    } else {
1966
1.92k
                        break;
1967
1.92k
                    }
1968
18.6k
                }
1969
3.82k
                i = j - 1;
1970
1971
3.82k
                PyObject *concat_str = PyUnicodeWriter_Finish(writer);
1972
3.82k
                if (concat_str == NULL) {
1973
0
                    return NULL;
1974
0
                }
1975
3.82k
                if (_PyArena_AddPyObject(p->arena, concat_str) < 0) {
1976
0
                    Py_DECREF(concat_str);
1977
0
                    return NULL;
1978
0
                }
1979
3.82k
                elem = _PyAST_Constant(concat_str, kind, first_elem->lineno,
1980
3.82k
                                       first_elem->col_offset,
1981
3.82k
                                       last_elem->end_lineno,
1982
3.82k
                                       last_elem->end_col_offset, p->arena);
1983
3.82k
                if (elem == NULL) {
1984
0
                    return NULL;
1985
0
                }
1986
3.82k
            }
1987
1988
            /* Drop all empty contanst strings */
1989
26.6k
            if (PyUnicode_CheckExact(elem->v.Constant.value) &&
1990
26.6k
                PyUnicode_GET_LENGTH(elem->v.Constant.value) == 0) {
1991
333
                continue;
1992
333
            }
1993
26.6k
        }
1994
1995
50.6k
        asdl_seq_SET(values, current_pos++, elem);
1996
50.6k
    }
1997
1998
12.6k
    assert(current_pos == n_elements);
1999
12.6k
    return values;
2000
12.6k
}
2001
2002
static expr_ty
2003
_build_concatenated_joined_str(Parser *p, asdl_expr_seq *strings,
2004
                               int lineno, int col_offset, int end_lineno,
2005
                               int end_col_offset, PyArena *arena)
2006
10.9k
{
2007
10.9k
    asdl_expr_seq *values = _build_concatenated_str(p, strings, lineno,
2008
10.9k
        col_offset, end_lineno, end_col_offset, arena);
2009
10.9k
    if (!values) {
2010
0
        return NULL;
2011
0
    }
2012
10.9k
    return _PyAST_JoinedStr(values, lineno, col_offset, end_lineno, end_col_offset, p->arena);
2013
10.9k
}
2014
2015
expr_ty
2016
_PyPegen_concatenate_tstrings(Parser *p, asdl_expr_seq *strings,
2017
                               int lineno, int col_offset, int end_lineno,
2018
                               int end_col_offset, PyArena *arena)
2019
1.68k
{
2020
1.68k
    asdl_expr_seq *values = _build_concatenated_str(p, strings, lineno,
2021
1.68k
        col_offset, end_lineno, end_col_offset, arena);
2022
1.68k
    if (!values) {
2023
0
        return NULL;
2024
0
    }
2025
1.68k
    return _PyAST_TemplateStr(values, lineno, col_offset, end_lineno,
2026
1.68k
        end_col_offset, arena);
2027
1.68k
}
2028
2029
expr_ty
2030
_PyPegen_concatenate_strings(Parser *p, asdl_expr_seq *strings,
2031
                             int lineno, int col_offset, int end_lineno,
2032
                             int end_col_offset, PyArena *arena)
2033
28.6k
{
2034
28.6k
    Py_ssize_t len = asdl_seq_LEN(strings);
2035
28.6k
    assert(len > 0);
2036
2037
28.6k
    int f_string_found = 0;
2038
28.6k
    int unicode_string_found = 0;
2039
28.6k
    int bytes_found = 0;
2040
2041
28.6k
    Py_ssize_t i = 0;
2042
93.9k
    for (i = 0; i < len; i++) {
2043
65.3k
        expr_ty elem = asdl_seq_GET(strings, i);
2044
65.3k
        switch(elem->kind) {
2045
48.1k
            case Constant_kind:
2046
48.1k
                if (PyBytes_CheckExact(elem->v.Constant.value)) {
2047
4.63k
                    bytes_found = 1;
2048
43.5k
                } else {
2049
43.5k
                    unicode_string_found = 1;
2050
43.5k
                }
2051
48.1k
                break;
2052
13.6k
            case JoinedStr_kind:
2053
13.6k
                f_string_found = 1;
2054
13.6k
                break;
2055
0
            case TemplateStr_kind:
2056
                // python.gram handles this; we should never get here
2057
0
                assert(0);
2058
0
                break;
2059
3.44k
            default:
2060
3.44k
                f_string_found = 1;
2061
3.44k
                break;
2062
65.3k
        }
2063
65.3k
    }
2064
2065
    // Cannot mix unicode and bytes
2066
28.6k
    if ((unicode_string_found || f_string_found) && bytes_found) {
2067
4
        RAISE_SYNTAX_ERROR("cannot mix bytes and nonbytes literals");
2068
4
        return NULL;
2069
4
    }
2070
2071
    // If it's only bytes or only unicode string, do a simple concat
2072
28.6k
    if (!f_string_found) {
2073
17.6k
        if (len == 1) {
2074
14.9k
            return asdl_seq_GET(strings, 0);
2075
14.9k
        }
2076
2.75k
        else if (bytes_found) {
2077
776
            return _build_concatenated_bytes(p, strings, lineno, col_offset,
2078
776
                end_lineno, end_col_offset, arena);
2079
776
        }
2080
1.97k
        else {
2081
1.97k
            return _build_concatenated_unicode(p, strings, lineno, col_offset,
2082
1.97k
                end_lineno, end_col_offset, arena);
2083
1.97k
        }
2084
17.6k
    }
2085
2086
10.9k
    return _build_concatenated_joined_str(p, strings, lineno,
2087
10.9k
        col_offset, end_lineno, end_col_offset, arena);
2088
28.6k
}
2089
2090
static int
2091
_warn_relative_import_of_lazy(Parser *p, asdl_seq *dots, expr_ty module)
2092
707
{
2093
    // Warn about `from . lazy import x`: the whitespace between the dots and
2094
    // the module name is insignificant, so this is parsed exactly like
2095
    // `from .lazy import x` (an import of the relative module "lazy"), but it
2096
    // is most likely a transposition of `lazy from . import x` (PEP 810).
2097
707
    if (p->call_invalid_rules) {
2098
294
        return 0;
2099
294
    }
2100
2101
    // Only fire if there is whitespace between the last dot and the name,
2102
    // i.e. not for the common `from .lazy import x` spelling.
2103
413
    Token *last_dot = asdl_seq_GET_UNTYPED(dots, asdl_seq_LEN(dots) - 1);
2104
413
    if (
2105
413
        last_dot->end_lineno == module->lineno
2106
413
        && last_dot->end_col_offset == module->col_offset
2107
413
    ) {
2108
149
        return 0;
2109
149
    }
2110
2111
264
    int count = _PyPegen_seq_count_dots(dots);
2112
264
    char *buf = PyMem_RawMalloc(count + 1);
2113
264
    if (buf == NULL) {
2114
0
        PyErr_NoMemory();
2115
0
        return -1;
2116
0
    }
2117
264
    memset(buf, '.', count);
2118
264
    buf[count] = '\0';
2119
2120
264
    PyObject *msg = PyUnicode_FromFormat(
2121
264
        "'from %s lazy import' is the same as 'from %slazy import'; "
2122
264
        "did you mean 'lazy from %s import'?",
2123
264
        buf, buf, buf);
2124
264
    PyMem_RawFree(buf);
2125
264
    if (msg == NULL) {
2126
0
        return -1;
2127
0
    }
2128
2129
264
    _PyTokenizer_Info info = _PyTokenizer_GetInfo(p->tok);
2130
264
    int res = _PyErr_EmitSyntaxWarning(msg,
2131
264
                                       info.filename,
2132
264
                                       module->lineno,
2133
264
                                       module->col_offset + 1,
2134
264
                                       module->end_lineno,
2135
264
                                       module->end_col_offset + 1,
2136
264
                                       info.module);
2137
264
    Py_DECREF(msg);
2138
264
    return res;
2139
264
}
2140
2141
stmt_ty
2142
_PyPegen_checked_from_import(Parser *p, asdl_seq *dots, expr_ty module_name,
2143
                             asdl_alias_seq *names, expr_ty lazy_token, int lineno,
2144
                             int col_offset, int end_lineno, int end_col_offset,
2145
                             PyArena *arena)
2146
3.81k
{
2147
3.81k
    identifier module = module_name->v.Name.id;
2148
3.81k
    int level = _PyPegen_seq_count_dots(dots);
2149
3.81k
    if (level == 0 && PyUnicode_CompareWithASCIIString(module, "__future__") == 0) {
2150
834
        if (lazy_token) {
2151
1
            RAISE_SYNTAX_ERROR_KNOWN_LOCATION(lazy_token,
2152
1
                "lazy from __future__ import is not allowed");
2153
1
            return NULL;
2154
1
        }
2155
2.03k
        for (Py_ssize_t i = 0; i < asdl_seq_LEN(names); i++) {
2156
1.20k
            alias_ty alias = asdl_seq_GET(names, i);
2157
1.20k
            if (PyUnicode_CompareWithASCIIString(alias->name, "barry_as_FLUFL") == 0) {
2158
299
                p->flags |= PyPARSE_BARRY_AS_BDFL;
2159
299
                p->tok->barry_as_bdfl = 1;
2160
299
            }
2161
1.20k
        }
2162
833
    }
2163
2.98k
    else if (
2164
2.98k
        level > 0
2165
1.96k
        && lazy_token == NULL
2166
1.92k
        && PyUnicode_CompareWithASCIIString(module, "lazy") == 0
2167
2.98k
    ) {
2168
707
        if (_warn_relative_import_of_lazy(p, dots, module_name) < 0) {
2169
0
            return NULL;
2170
0
        }
2171
707
    }
2172
3.81k
    return _PyAST_ImportFrom(module, names, level, lazy_token ? 1 : 0, lineno,
2173
3.81k
                             col_offset, end_lineno, end_col_offset, arena);
2174
3.81k
}
2175
2176
asdl_stmt_seq*
2177
27.7k
_PyPegen_register_stmts(Parser *p, asdl_stmt_seq* stmts) {
2178
27.7k
    if (!p->call_invalid_rules) {
2179
19.5k
        return stmts;
2180
19.5k
    }
2181
8.25k
    Py_ssize_t len = asdl_seq_LEN(stmts);
2182
8.25k
    if (len == 0) {
2183
0
        return stmts;
2184
0
    }
2185
8.25k
    stmt_ty last_stmt = asdl_seq_GET(stmts, len - 1);
2186
8.25k
    if (p->last_stmt_location.lineno > last_stmt->lineno) {
2187
441
        return stmts;
2188
441
    }
2189
7.81k
    p->last_stmt_location.lineno = last_stmt->lineno;
2190
7.81k
    p->last_stmt_location.col_offset = last_stmt->col_offset;
2191
7.81k
    p->last_stmt_location.end_lineno = last_stmt->end_lineno;
2192
7.81k
    p->last_stmt_location.end_col_offset = last_stmt->end_col_offset;
2193
7.81k
    return stmts;
2194
8.25k
}