Coverage Report

Created: 2026-08-13 06:33

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