Coverage Report

Created: 2026-10-17 06:15

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
59.0k
{
15
59.0k
    return &_PyRuntime.parser.dummy_name;
16
59.0k
}
17
18
/* Creates a single-element asdl_seq* that contains a */
19
asdl_seq *
20
_PyPegen_singleton_seq(Parser *p, void *a)
21
132k
{
22
132k
    assert(a != NULL);
23
132k
    asdl_seq *seq = (asdl_seq*)_Py_asdl_generic_seq_new(1, p->arena);
24
132k
    if (!seq) {
25
0
        return NULL;
26
0
    }
27
132k
    asdl_seq_SET_UNTYPED(seq, 0, a);
28
132k
    return seq;
29
132k
}
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
306k
{
35
306k
    assert(a != NULL);
36
306k
    if (!seq) {
37
7.69k
        return _PyPegen_singleton_seq(p, a);
38
7.69k
    }
39
40
298k
    asdl_seq *new_seq = (asdl_seq*)_Py_asdl_generic_seq_new(asdl_seq_LEN(seq) + 1, p->arena);
41
298k
    if (!new_seq) {
42
0
        return NULL;
43
0
    }
44
45
298k
    asdl_seq_SET_UNTYPED(new_seq, 0, a);
46
531k
    for (Py_ssize_t i = 1, l = asdl_seq_LEN(new_seq); i < l; i++) {
47
232k
        asdl_seq_SET_UNTYPED(new_seq, i, asdl_seq_GET_UNTYPED(seq, i - 1));
48
232k
    }
49
298k
    return new_seq;
50
298k
}
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.6k
{
76
18.6k
    Py_ssize_t size = 0;
77
104k
    for (Py_ssize_t i = 0, l = asdl_seq_LEN(seqs); i < l; i++) {
78
86.2k
        asdl_seq *inner_seq = asdl_seq_GET_UNTYPED(seqs, i);
79
86.2k
        size += asdl_seq_LEN(inner_seq);
80
86.2k
    }
81
18.6k
    return size;
82
18.6k
}
83
84
/* Flattens an asdl_seq* of asdl_seq*s */
85
asdl_seq *
86
_PyPegen_seq_flatten(Parser *p, asdl_seq *seqs)
87
18.6k
{
88
18.6k
    Py_ssize_t flattened_seq_size = _get_flattened_seq_size(seqs);
89
18.6k
    assert(flattened_seq_size > 0);
90
91
18.6k
    asdl_seq *flattened_seq = (asdl_seq*)_Py_asdl_generic_seq_new(flattened_seq_size, p->arena);
92
18.6k
    if (!flattened_seq) {
93
0
        return NULL;
94
0
    }
95
96
18.6k
    int flattened_seq_idx = 0;
97
104k
    for (Py_ssize_t i = 0, l = asdl_seq_LEN(seqs); i < l; i++) {
98
86.2k
        asdl_seq *inner_seq = asdl_seq_GET_UNTYPED(seqs, i);
99
183k
        for (Py_ssize_t j = 0, li = asdl_seq_LEN(inner_seq); j < li; j++) {
100
97.4k
            asdl_seq_SET_UNTYPED(flattened_seq, flattened_seq_idx++, asdl_seq_GET_UNTYPED(inner_seq, j));
101
97.4k
        }
102
86.2k
    }
103
18.6k
    assert(flattened_seq_idx == flattened_seq_size);
104
105
18.6k
    return flattened_seq;
106
18.6k
}
107
108
void *
109
_PyPegen_seq_last_item(asdl_seq *seq)
110
72
{
111
72
    Py_ssize_t len = asdl_seq_LEN(seq);
112
72
    return asdl_seq_GET_UNTYPED(seq, len - 1);
113
72
}
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
6.41k
{
125
6.41k
    assert(first_name != NULL && second_name != NULL);
126
6.41k
    PyObject *uni = PyUnicode_FromFormat("%U.%U",
127
6.41k
            first_name->v.Name.id, second_name->v.Name.id);
128
6.41k
    if (!uni) {
129
0
        return NULL;
130
0
    }
131
6.41k
    PyInterpreterState *interp = _PyInterpreterState_GET();
132
6.41k
    _PyUnicode_InternImmortal(interp, &uni);
133
6.41k
    if (_PyArena_AddPyObject(p->arena, uni) < 0) {
134
0
        Py_DECREF(uni);
135
0
        return NULL;
136
0
    }
137
138
6.41k
    return _PyAST_Name(uni, Load, EXTRA_EXPR(first_name, second_name));
139
6.41k
}
140
141
/* Counts the total number of dots in seq's tokens */
142
int
143
_PyPegen_seq_count_dots(asdl_seq *seq)
144
5.75k
{
145
5.75k
    int number_of_dots = 0;
146
16.8k
    for (Py_ssize_t i = 0, l = asdl_seq_LEN(seq); i < l; i++) {
147
11.0k
        Token *current_expr = asdl_seq_GET_UNTYPED(seq, i);
148
11.0k
        switch (current_expr->type) {
149
4.30k
            case ELLIPSIS:
150
4.30k
                number_of_dots += 3;
151
4.30k
                break;
152
6.78k
            case DOT:
153
6.78k
                number_of_dots += 1;
154
6.78k
                break;
155
0
            default:
156
0
                Py_UNREACHABLE();
157
11.0k
        }
158
11.0k
    }
159
160
5.75k
    return number_of_dots;
161
5.75k
}
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.69k
                        int end_col_offset, PyArena *arena) {
167
1.69k
    PyObject *str = PyUnicode_InternFromString("*");
168
1.69k
    if (!str) {
169
0
        return NULL;
170
0
    }
171
1.69k
    if (_PyArena_AddPyObject(p->arena, str) < 0) {
172
0
        Py_DECREF(str);
173
0
        return NULL;
174
0
    }
175
1.69k
    return _PyAST_alias(str, NULL, lineno, col_offset, end_lineno, end_col_offset, arena);
176
1.69k
}
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
2.03k
{
182
2.03k
    Py_ssize_t len = asdl_seq_LEN(seq);
183
2.03k
    assert(len > 0);
184
185
2.03k
    asdl_identifier_seq *new_seq = _Py_asdl_identifier_seq_new(len, p->arena);
186
2.03k
    if (!new_seq) {
187
0
        return NULL;
188
0
    }
189
7.52k
    for (Py_ssize_t i = 0; i < len; i++) {
190
5.49k
        expr_ty e = asdl_seq_GET(seq, i);
191
5.49k
        asdl_seq_SET(new_seq, i, e->v.Name.id);
192
5.49k
    }
193
2.03k
    return new_seq;
194
2.03k
}
195
196
/* Constructs a CmpopExprPair */
197
CmpopExprPair *
198
_PyPegen_cmpop_expr_pair(Parser *p, cmpop_ty cmpop, expr_ty expr)
199
18.7k
{
200
18.7k
    assert(expr != NULL);
201
18.7k
    CmpopExprPair *a = _PyArena_Malloc(p->arena, sizeof(CmpopExprPair));
202
18.7k
    if (!a) {
203
0
        return NULL;
204
0
    }
205
18.7k
    a->cmpop = cmpop;
206
18.7k
    a->expr = expr;
207
18.7k
    return a;
208
18.7k
}
209
210
asdl_int_seq *
211
_PyPegen_get_cmpops(Parser *p, asdl_seq *seq)
212
6.85k
{
213
6.85k
    Py_ssize_t len = asdl_seq_LEN(seq);
214
6.85k
    assert(len > 0);
215
216
6.85k
    asdl_int_seq *new_seq = _Py_asdl_int_seq_new(len, p->arena);
217
6.85k
    if (!new_seq) {
218
0
        return NULL;
219
0
    }
220
25.0k
    for (Py_ssize_t i = 0; i < len; i++) {
221
18.1k
        CmpopExprPair *pair = asdl_seq_GET_UNTYPED(seq, i);
222
18.1k
        asdl_seq_SET(new_seq, i, pair->cmpop);
223
18.1k
    }
224
6.85k
    return new_seq;
225
6.85k
}
226
227
asdl_expr_seq *
228
_PyPegen_get_exprs(Parser *p, asdl_seq *seq)
229
6.85k
{
230
6.85k
    Py_ssize_t len = asdl_seq_LEN(seq);
231
6.85k
    assert(len > 0);
232
233
6.85k
    asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena);
234
6.85k
    if (!new_seq) {
235
0
        return NULL;
236
0
    }
237
25.0k
    for (Py_ssize_t i = 0; i < len; i++) {
238
18.1k
        CmpopExprPair *pair = asdl_seq_GET_UNTYPED(seq, i);
239
18.1k
        asdl_seq_SET(new_seq, i, pair->expr);
240
18.1k
    }
241
6.85k
    return new_seq;
242
6.85k
}
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
5.77k
{
248
5.77k
    Py_ssize_t len = asdl_seq_LEN(seq);
249
5.77k
    if (len == 0) {
250
4.30k
        return NULL;
251
4.30k
    }
252
253
1.47k
    asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena);
254
1.47k
    if (!new_seq) {
255
0
        return NULL;
256
0
    }
257
3.92k
    for (Py_ssize_t i = 0; i < len; i++) {
258
2.44k
        expr_ty e = asdl_seq_GET(seq, i);
259
2.44k
        expr_ty new_e = _PyPegen_set_expr_context(p, e, ctx);
260
2.44k
        if (!new_e) {
261
0
            return NULL;
262
0
        }
263
2.44k
        asdl_seq_SET(new_seq, i, new_e);
264
2.44k
    }
265
1.47k
    return new_seq;
266
1.47k
}
267
268
static expr_ty
269
_set_name_context(Parser *p, expr_ty e, expr_context_ty ctx)
270
166k
{
271
166k
    return _PyAST_Name(e->v.Name.id, ctx, EXTRA_EXPR(e, e));
272
166k
}
273
274
static expr_ty
275
_set_tuple_context(Parser *p, expr_ty e, expr_context_ty ctx)
276
4.51k
{
277
4.51k
    asdl_expr_seq *seq = _set_seq_context(p, e->v.Tuple.elts, ctx);
278
4.51k
    if (!seq && PyErr_Occurred()) {
279
0
        return NULL;
280
0
    }
281
4.51k
    return _PyAST_Tuple(seq, ctx, EXTRA_EXPR(e, e));
282
4.51k
}
283
284
static expr_ty
285
_set_list_context(Parser *p, expr_ty e, expr_context_ty ctx)
286
1.26k
{
287
1.26k
    asdl_expr_seq *seq = _set_seq_context(p, e->v.List.elts, ctx);
288
1.26k
    if (!seq && PyErr_Occurred()) {
289
0
        return NULL;
290
0
    }
291
1.26k
    return _PyAST_List(seq, ctx, EXTRA_EXPR(e, e));
292
1.26k
}
293
294
static expr_ty
295
_set_subscript_context(Parser *p, expr_ty e, expr_context_ty ctx)
296
1.38k
{
297
1.38k
    return _PyAST_Subscript(e->v.Subscript.value, e->v.Subscript.slice,
298
1.38k
                            ctx, EXTRA_EXPR(e, e));
299
1.38k
}
300
301
static expr_ty
302
_set_attribute_context(Parser *p, expr_ty e, expr_context_ty ctx)
303
6.48k
{
304
6.48k
    return _PyAST_Attribute(e->v.Attribute.value, e->v.Attribute.attr,
305
6.48k
                            ctx, EXTRA_EXPR(e, e));
306
6.48k
}
307
308
static expr_ty
309
_set_starred_context(Parser *p, expr_ty e, expr_context_ty ctx)
310
81
{
311
81
    expr_ty inner = _PyPegen_set_expr_context(p, e->v.Starred.value, ctx);
312
81
    if (!inner) {
313
0
        return NULL;
314
0
    }
315
81
    return _PyAST_Starred(inner, ctx, EXTRA_EXPR(e, e));
316
81
}
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
180k
{
322
180k
    assert(expr != NULL);
323
324
180k
    expr_ty new = NULL;
325
180k
    switch (expr->kind) {
326
166k
        case Name_kind:
327
166k
            new = _set_name_context(p, expr, ctx);
328
166k
            break;
329
4.51k
        case Tuple_kind:
330
4.51k
            new = _set_tuple_context(p, expr, ctx);
331
4.51k
            break;
332
1.26k
        case List_kind:
333
1.26k
            new = _set_list_context(p, expr, ctx);
334
1.26k
            break;
335
1.38k
        case Subscript_kind:
336
1.38k
            new = _set_subscript_context(p, expr, ctx);
337
1.38k
            break;
338
6.48k
        case Attribute_kind:
339
6.48k
            new = _set_attribute_context(p, expr, ctx);
340
6.48k
            break;
341
81
        case Starred_kind:
342
81
            new = _set_starred_context(p, expr, ctx);
343
81
            break;
344
0
        default:
345
0
            new = expr;
346
180k
    }
347
180k
    return new;
348
180k
}
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
339k
{
355
339k
    assert(expr != NULL);
356
339k
    assert(targets_type != FOR_TARGETS);
357
339k
    if (_PyPegen_get_invalid_target(expr, targets_type) != NULL) {
358
182k
        return NULL;
359
182k
    }
360
156k
    return _PyPegen_set_expr_context(
361
156k
        p, expr, targets_type == DEL_TARGETS ? Del : Store);
362
339k
}
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
26.7k
{
368
26.7k
    KeyValuePair *a = _PyArena_Malloc(p->arena, sizeof(KeyValuePair));
369
26.7k
    if (!a) {
370
0
        return NULL;
371
0
    }
372
26.7k
    a->key = key;
373
26.7k
    a->value = value;
374
26.7k
    return a;
375
26.7k
}
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
3.79k
{
381
3.79k
    Py_ssize_t len = asdl_seq_LEN(seq);
382
3.79k
    asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena);
383
3.79k
    if (!new_seq) {
384
0
        return NULL;
385
0
    }
386
19.1k
    for (Py_ssize_t i = 0; i < len; i++) {
387
15.3k
        KeyValuePair *pair = asdl_seq_GET_UNTYPED(seq, i);
388
15.3k
        asdl_seq_SET(new_seq, i, pair->key);
389
15.3k
    }
390
3.79k
    return new_seq;
391
3.79k
}
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
3.79k
{
397
3.79k
    Py_ssize_t len = asdl_seq_LEN(seq);
398
3.79k
    asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena);
399
3.79k
    if (!new_seq) {
400
0
        return NULL;
401
0
    }
402
19.1k
    for (Py_ssize_t i = 0; i < len; i++) {
403
15.3k
        KeyValuePair *pair = asdl_seq_GET_UNTYPED(seq, i);
404
15.3k
        asdl_seq_SET(new_seq, i, pair->value);
405
15.3k
    }
406
3.79k
    return new_seq;
407
3.79k
}
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
12.0k
{
413
12.0k
    KeyPatternPair *a = _PyArena_Malloc(p->arena, sizeof(KeyPatternPair));
414
12.0k
    if (!a) {
415
0
        return NULL;
416
0
    }
417
12.0k
    a->key = key;
418
12.0k
    a->pattern = pattern;
419
12.0k
    return a;
420
12.0k
}
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.59k
{
426
1.59k
    Py_ssize_t len = asdl_seq_LEN(seq);
427
1.59k
    asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena);
428
1.59k
    if (!new_seq) {
429
0
        return NULL;
430
0
    }
431
3.98k
    for (Py_ssize_t i = 0; i < len; i++) {
432
2.38k
        KeyPatternPair *pair = asdl_seq_GET_UNTYPED(seq, i);
433
2.38k
        asdl_seq_SET(new_seq, i, pair->key);
434
2.38k
    }
435
1.59k
    return new_seq;
436
1.59k
}
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.59k
{
442
1.59k
    Py_ssize_t len = asdl_seq_LEN(seq);
443
1.59k
    asdl_pattern_seq *new_seq = _Py_asdl_pattern_seq_new(len, p->arena);
444
1.59k
    if (!new_seq) {
445
0
        return NULL;
446
0
    }
447
3.98k
    for (Py_ssize_t i = 0; i < len; i++) {
448
2.38k
        KeyPatternPair *pair = asdl_seq_GET_UNTYPED(seq, i);
449
2.38k
        asdl_seq_SET(new_seq, i, pair->pattern);
450
2.38k
    }
451
1.59k
    return new_seq;
452
1.59k
}
453
454
/* Constructs a NameDefaultPair */
455
NameDefaultPair *
456
_PyPegen_name_default_pair(Parser *p, arg_ty arg, expr_ty value, Token *tc)
457
318k
{
458
318k
    NameDefaultPair *a = _PyArena_Malloc(p->arena, sizeof(NameDefaultPair));
459
318k
    if (!a) {
460
0
        return NULL;
461
0
    }
462
318k
    a->arg = _PyPegen_add_type_comment_to_arg(p, arg, tc);
463
318k
    if (!a->arg) {
464
0
        return NULL;
465
0
    }
466
318k
    a->value = value;
467
318k
    return a;
468
318k
}
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.46k
{
474
5.46k
    SlashWithDefault *a = _PyArena_Malloc(p->arena, sizeof(SlashWithDefault));
475
5.46k
    if (!a) {
476
0
        return NULL;
477
0
    }
478
5.46k
    a->plain_names = plain_names;
479
5.46k
    a->names_with_defaults = names_with_defaults;
480
5.46k
    return a;
481
5.46k
}
482
483
/* Constructs a StarEtc */
484
StarEtc *
485
_PyPegen_star_etc(Parser *p, arg_ty vararg, asdl_seq *kwonlyargs, arg_ty kwarg)
486
6.63k
{
487
6.63k
    StarEtc *a = _PyArena_Malloc(p->arena, sizeof(StarEtc));
488
6.63k
    if (!a) {
489
0
        return NULL;
490
0
    }
491
6.63k
    a->vararg = vararg;
492
6.63k
    a->kwonlyargs = kwonlyargs;
493
6.63k
    a->kwarg = kwarg;
494
6.63k
    return a;
495
6.63k
}
496
497
asdl_seq *
498
_PyPegen_join_sequences(Parser *p, asdl_seq *a, asdl_seq *b)
499
179k
{
500
179k
    Py_ssize_t first_len = asdl_seq_LEN(a);
501
179k
    Py_ssize_t second_len = asdl_seq_LEN(b);
502
179k
    asdl_seq *new_seq = (asdl_seq*)_Py_asdl_generic_seq_new(first_len + second_len, p->arena);
503
179k
    if (!new_seq) {
504
0
        return NULL;
505
0
    }
506
507
179k
    int k = 0;
508
371k
    for (Py_ssize_t i = 0; i < first_len; i++) {
509
191k
        asdl_seq_SET_UNTYPED(new_seq, k++, asdl_seq_GET_UNTYPED(a, i));
510
191k
    }
511
190k
    for (Py_ssize_t i = 0; i < second_len; i++) {
512
11.1k
        asdl_seq_SET_UNTYPED(new_seq, k++, asdl_seq_GET_UNTYPED(b, i));
513
11.1k
    }
514
515
179k
    return new_seq;
516
179k
}
517
518
static asdl_arg_seq*
519
_get_names(Parser *p, asdl_seq *names_with_defaults)
520
186k
{
521
186k
    Py_ssize_t len = asdl_seq_LEN(names_with_defaults);
522
186k
    asdl_arg_seq *seq = _Py_asdl_arg_seq_new(len, p->arena);
523
186k
    if (!seq) {
524
0
        return NULL;
525
0
    }
526
197k
    for (Py_ssize_t i = 0; i < len; i++) {
527
11.1k
        NameDefaultPair *pair = asdl_seq_GET_UNTYPED(names_with_defaults, i);
528
11.1k
        asdl_seq_SET(seq, i, pair->arg);
529
11.1k
    }
530
186k
    return seq;
531
186k
}
532
533
static asdl_expr_seq *
534
_get_defaults(Parser *p, asdl_seq *names_with_defaults)
535
186k
{
536
186k
    Py_ssize_t len = asdl_seq_LEN(names_with_defaults);
537
186k
    asdl_expr_seq *seq = _Py_asdl_expr_seq_new(len, p->arena);
538
186k
    if (!seq) {
539
0
        return NULL;
540
0
    }
541
197k
    for (Py_ssize_t i = 0; i < len; i++) {
542
11.1k
        NameDefaultPair *pair = asdl_seq_GET_UNTYPED(names_with_defaults, i);
543
11.1k
        asdl_seq_SET(seq, i, pair->value);
544
11.1k
    }
545
186k
    return seq;
546
186k
}
547
548
static int
549
_make_posonlyargs(Parser *p,
550
                  asdl_arg_seq *slash_without_default,
551
                  SlashWithDefault *slash_with_default,
552
185k
                  asdl_arg_seq **posonlyargs) {
553
185k
    if (slash_without_default != NULL) {
554
1.26k
        *posonlyargs = slash_without_default;
555
1.26k
    }
556
184k
    else if (slash_with_default != NULL) {
557
1.76k
        asdl_arg_seq *slash_with_default_names =
558
1.76k
                _get_names(p, slash_with_default->names_with_defaults);
559
1.76k
        if (!slash_with_default_names) {
560
0
            return -1;
561
0
        }
562
1.76k
        *posonlyargs = (asdl_arg_seq*)_PyPegen_join_sequences(
563
1.76k
                p,
564
1.76k
                (asdl_seq*)slash_with_default->plain_names,
565
1.76k
                (asdl_seq*)slash_with_default_names);
566
1.76k
    }
567
182k
    else {
568
182k
        *posonlyargs = _Py_asdl_arg_seq_new(0, p->arena);
569
182k
    }
570
185k
    return *posonlyargs == NULL ? -1 : 0;
571
185k
}
572
573
static int
574
_make_posargs(Parser *p,
575
              asdl_arg_seq *plain_names,
576
              asdl_seq *names_with_default,
577
185k
              asdl_arg_seq **posargs) {
578
579
185k
    if (names_with_default != NULL) {
580
179k
        if (plain_names != NULL) {
581
175k
            asdl_arg_seq *names_with_default_names = _get_names(p, names_with_default);
582
175k
            if (!names_with_default_names) {
583
0
                return -1;
584
0
            }
585
175k
            *posargs = (asdl_arg_seq*)_PyPegen_join_sequences(
586
175k
                    p,(asdl_seq*)plain_names, (asdl_seq*)names_with_default_names);
587
175k
        }
588
4.12k
        else {
589
4.12k
            *posargs = _get_names(p, names_with_default);
590
4.12k
        }
591
179k
    }
592
6.04k
    else {
593
6.04k
        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.04k
        else {
600
6.04k
            *posargs = _Py_asdl_arg_seq_new(0, p->arena);
601
6.04k
        }
602
6.04k
    }
603
185k
    return *posargs == NULL ? -1 : 0;
604
185k
}
605
606
static int
607
_make_posdefaults(Parser *p,
608
                  SlashWithDefault *slash_with_default,
609
                  asdl_seq *names_with_default,
610
185k
                  asdl_expr_seq **posdefaults) {
611
185k
    if (slash_with_default != NULL && names_with_default != NULL) {
612
1.76k
        asdl_expr_seq *slash_with_default_values =
613
1.76k
                _get_defaults(p, slash_with_default->names_with_defaults);
614
1.76k
        if (!slash_with_default_values) {
615
0
            return -1;
616
0
        }
617
1.76k
        asdl_expr_seq *names_with_default_values = _get_defaults(p, names_with_default);
618
1.76k
        if (!names_with_default_values) {
619
0
            return -1;
620
0
        }
621
1.76k
        *posdefaults = (asdl_expr_seq*)_PyPegen_join_sequences(
622
1.76k
                p,
623
1.76k
                (asdl_seq*)slash_with_default_values,
624
1.76k
                (asdl_seq*)names_with_default_values);
625
1.76k
    }
626
183k
    else if (slash_with_default == NULL && names_with_default != NULL) {
627
177k
        *posdefaults = _get_defaults(p, names_with_default);
628
177k
    }
629
6.04k
    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.04k
    else {
633
6.04k
        *posdefaults = _Py_asdl_expr_seq_new(0, p->arena);
634
6.04k
    }
635
185k
    return *posdefaults == NULL ? -1 : 0;
636
185k
}
637
638
static int
639
_make_kwargs(Parser *p, StarEtc *star_etc,
640
             asdl_arg_seq **kwonlyargs,
641
185k
             asdl_expr_seq **kwdefaults) {
642
185k
    if (star_etc != NULL && star_etc->kwonlyargs != NULL) {
643
5.18k
        *kwonlyargs = _get_names(p, star_etc->kwonlyargs);
644
5.18k
    }
645
180k
    else {
646
180k
        *kwonlyargs = _Py_asdl_arg_seq_new(0, p->arena);
647
180k
    }
648
649
185k
    if (*kwonlyargs == NULL) {
650
0
        return -1;
651
0
    }
652
653
185k
    if (star_etc != NULL && star_etc->kwonlyargs != NULL) {
654
5.18k
        *kwdefaults = _get_defaults(p, star_etc->kwonlyargs);
655
5.18k
    }
656
180k
    else {
657
180k
        *kwdefaults = _Py_asdl_expr_seq_new(0, p->arena);
658
180k
    }
659
660
185k
    if (*kwdefaults == NULL) {
661
0
        return -1;
662
0
    }
663
664
185k
    return 0;
665
185k
}
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
185k
{
673
185k
    asdl_arg_seq *posonlyargs;
674
185k
    if (_make_posonlyargs(p, slash_without_default, slash_with_default, &posonlyargs) == -1) {
675
0
        return NULL;
676
0
    }
677
678
185k
    asdl_arg_seq *posargs;
679
185k
    if (_make_posargs(p, plain_names, names_with_default, &posargs) == -1) {
680
0
        return NULL;
681
0
    }
682
683
185k
    asdl_expr_seq *posdefaults;
684
185k
    if (_make_posdefaults(p,slash_with_default, names_with_default, &posdefaults) == -1) {
685
0
        return NULL;
686
0
    }
687
688
185k
    arg_ty vararg = NULL;
689
185k
    if (star_etc != NULL && star_etc->vararg != NULL) {
690
3.84k
        vararg = star_etc->vararg;
691
3.84k
    }
692
693
185k
    asdl_arg_seq *kwonlyargs;
694
185k
    asdl_expr_seq *kwdefaults;
695
185k
    if (_make_kwargs(p, star_etc, &kwonlyargs, &kwdefaults) == -1) {
696
0
        return NULL;
697
0
    }
698
699
185k
    arg_ty kwarg = NULL;
700
185k
    if (star_etc != NULL && star_etc->kwarg != NULL) {
701
1.52k
        kwarg = star_etc->kwarg;
702
1.52k
    }
703
704
185k
    return _PyAST_arguments(posonlyargs, posargs, vararg, kwonlyargs,
705
185k
                            kwdefaults, kwarg, posdefaults, p->arena);
706
185k
}
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.44k
{
714
2.44k
    asdl_arg_seq *posonlyargs = _Py_asdl_arg_seq_new(0, p->arena);
715
2.44k
    if (!posonlyargs) {
716
0
        return NULL;
717
0
    }
718
2.44k
    asdl_arg_seq *posargs = _Py_asdl_arg_seq_new(0, p->arena);
719
2.44k
    if (!posargs) {
720
0
        return NULL;
721
0
    }
722
2.44k
    asdl_expr_seq *posdefaults = _Py_asdl_expr_seq_new(0, p->arena);
723
2.44k
    if (!posdefaults) {
724
0
        return NULL;
725
0
    }
726
2.44k
    asdl_arg_seq *kwonlyargs = _Py_asdl_arg_seq_new(0, p->arena);
727
2.44k
    if (!kwonlyargs) {
728
0
        return NULL;
729
0
    }
730
2.44k
    asdl_expr_seq *kwdefaults = _Py_asdl_expr_seq_new(0, p->arena);
731
2.44k
    if (!kwdefaults) {
732
0
        return NULL;
733
0
    }
734
735
2.44k
    return _PyAST_arguments(posonlyargs, posargs, NULL, kwonlyargs,
736
2.44k
                            kwdefaults, NULL, posdefaults, p->arena);
737
2.44k
}
738
739
/* Encapsulates the value of an operator_ty into an AugOperator struct */
740
AugOperator *
741
_PyPegen_augoperator(Parser *p, operator_ty kind)
742
2.57k
{
743
2.57k
    AugOperator *a = _PyArena_Malloc(p->arena, sizeof(AugOperator));
744
2.57k
    if (!a) {
745
0
        return NULL;
746
0
    }
747
2.57k
    a->kind = kind;
748
2.57k
    return a;
749
2.57k
}
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
670
{
755
670
    assert(function_def != NULL);
756
670
    if (function_def->kind == AsyncFunctionDef_kind) {
757
313
        return _PyAST_AsyncFunctionDef(
758
313
            function_def->v.AsyncFunctionDef.name,
759
313
            function_def->v.AsyncFunctionDef.args,
760
313
            function_def->v.AsyncFunctionDef.body, decorators,
761
313
            function_def->v.AsyncFunctionDef.returns,
762
313
            function_def->v.AsyncFunctionDef.type_comment,
763
313
            function_def->v.AsyncFunctionDef.type_params,
764
313
            function_def->lineno, function_def->col_offset,
765
313
            function_def->end_lineno, function_def->end_col_offset, p->arena);
766
313
    }
767
768
357
    return _PyAST_FunctionDef(
769
357
        function_def->v.FunctionDef.name,
770
357
        function_def->v.FunctionDef.args,
771
357
        function_def->v.FunctionDef.body, decorators,
772
357
        function_def->v.FunctionDef.returns,
773
357
        function_def->v.FunctionDef.type_comment,
774
357
        function_def->v.FunctionDef.type_params,
775
357
        function_def->lineno, function_def->col_offset,
776
357
        function_def->end_lineno, function_def->end_col_offset, p->arena);
777
670
}
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
322
{
783
322
    assert(class_def != NULL);
784
322
    return _PyAST_ClassDef(
785
322
        class_def->v.ClassDef.name,
786
322
        class_def->v.ClassDef.bases, class_def->v.ClassDef.keywords,
787
322
        class_def->v.ClassDef.body, decorators,
788
322
        class_def->v.ClassDef.type_params,
789
322
        class_def->lineno, class_def->col_offset, class_def->end_lineno,
790
322
        class_def->end_col_offset, p->arena);
791
322
}
792
793
/* Construct a KeywordOrStarred */
794
KeywordOrStarred *
795
_PyPegen_keyword_or_starred(Parser *p, void *element, int is_keyword)
796
27.6k
{
797
27.6k
    KeywordOrStarred *a = _PyArena_Malloc(p->arena, sizeof(KeywordOrStarred));
798
27.6k
    if (!a) {
799
0
        return NULL;
800
0
    }
801
27.6k
    a->element = element;
802
27.6k
    a->is_keyword = is_keyword;
803
27.6k
    return a;
804
27.6k
}
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
19.7k
{
810
19.7k
    int n = 0;
811
64.3k
    for (Py_ssize_t i = 0, l = asdl_seq_LEN(seq); i < l; i++) {
812
44.6k
        KeywordOrStarred *k = asdl_seq_GET_UNTYPED(seq, i);
813
44.6k
        if (!k->is_keyword) {
814
4.41k
            n++;
815
4.41k
        }
816
44.6k
    }
817
19.7k
    return n;
818
19.7k
}
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
9.88k
{
824
9.88k
    int new_len = _seq_number_of_starred_exprs(kwargs);
825
9.88k
    if (new_len == 0) {
826
9.20k
        return NULL;
827
9.20k
    }
828
681
    asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(new_len, p->arena);
829
681
    if (!new_seq) {
830
0
        return NULL;
831
0
    }
832
833
681
    int idx = 0;
834
4.02k
    for (Py_ssize_t i = 0, len = asdl_seq_LEN(kwargs); i < len; i++) {
835
3.34k
        KeywordOrStarred *k = asdl_seq_GET_UNTYPED(kwargs, i);
836
3.34k
        if (!k->is_keyword) {
837
2.20k
            asdl_seq_SET(new_seq, idx++, k->element);
838
2.20k
        }
839
3.34k
    }
840
681
    return new_seq;
841
681
}
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
9.88k
{
847
9.88k
    Py_ssize_t len = asdl_seq_LEN(kwargs);
848
9.88k
    Py_ssize_t new_len = len - _seq_number_of_starred_exprs(kwargs);
849
9.88k
    if (new_len == 0) {
850
0
        return NULL;
851
0
    }
852
9.88k
    asdl_keyword_seq *new_seq = _Py_asdl_keyword_seq_new(new_len, p->arena);
853
9.88k
    if (!new_seq) {
854
0
        return NULL;
855
0
    }
856
857
9.88k
    int idx = 0;
858
32.1k
    for (Py_ssize_t i = 0; i < len; i++) {
859
22.3k
        KeywordOrStarred *k = asdl_seq_GET_UNTYPED(kwargs, i);
860
22.3k
        if (k->is_keyword) {
861
20.1k
            asdl_seq_SET(new_seq, idx++, k->element);
862
20.1k
        }
863
22.3k
    }
864
9.88k
    return new_seq;
865
9.88k
}
866
867
expr_ty
868
_PyPegen_ensure_imaginary(Parser *p, expr_ty exp)
869
1.26k
{
870
1.26k
    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.26k
    return exp;
875
1.26k
}
876
877
expr_ty
878
_PyPegen_ensure_real(Parser *p, expr_ty exp)
879
3.22k
{
880
3.22k
    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.22k
    return exp;
885
3.22k
}
886
887
mod_ty
888
8.03k
_PyPegen_make_module(Parser *p, asdl_stmt_seq *a) {
889
8.03k
    asdl_type_ignore_seq *type_ignores = NULL;
890
8.03k
    Py_ssize_t num = p->type_ignore_comments.num_items;
891
8.03k
    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.03k
    return _PyAST_Module(a, type_ignores, p->arena);
911
8.03k
}
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
379k
{
930
379k
    if (tc == NULL) {
931
379k
        return a;
932
379k
    }
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.24k
_PyPegen_check_barry_as_flufl(Parser *p, Token* t) {
950
1.24k
    assert(t->bytes != NULL);
951
1.24k
    assert(t->type == NOTEQUAL);
952
953
1.24k
    const char* tok_str = PyBytes_AS_STRING(t->bytes);
954
1.24k
    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.24k
    if (!(p->flags & PyPARSE_BARRY_AS_BDFL)) {
959
1.04k
        return strcmp(tok_str, "!=");
960
1.04k
    }
961
194
    return 0;
962
1.24k
}
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.39k
        return 0;
968
3.39k
    }
969
9.11k
    const char* candidates[2] = {"print", "exec"};
970
27.1k
    for (int i=0; i<2; i++) {
971
18.2k
        if (PyUnicode_CompareWithASCIIString(name->v.Name.id, candidates[i]) == 0) {
972
211
            return 1;
973
211
        }
974
18.2k
    }
975
8.90k
    return 0;
976
9.11k
}
977
978
void *
979
_PyPegen_raise_error_for_missing_comma(Parser *p, expr_ty a, expr_ty b)
980
6.05k
{
981
    // Don't raise for legacy statements like "print x" or "exec x"
982
6.05k
    if (_PyPegen_check_legacy_stmt(p, a)) {
983
202
        return NULL;
984
202
    }
985
    // Only raise inside parentheses/brackets (level > 0)
986
5.85k
    if (p->tokens[p->mark - 1]->level == 0) {
987
5.71k
        return NULL;
988
5.71k
    }
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
144
    if (a->end_lineno > a->lineno) {
994
5
        return RAISE_ERROR_KNOWN_LOCATION(
995
5
            p, PyExc_SyntaxError, a->end_lineno, a->col_offset,
996
5
            a->end_lineno, a->end_col_offset,
997
5
            "invalid syntax. Perhaps you forgot a comma?"
998
5
        );
999
5
    }
1000
139
    return RAISE_ERROR_KNOWN_LOCATION(
1001
139
        p, PyExc_SyntaxError, a->lineno, a->col_offset,
1002
139
        b->end_lineno, b->end_col_offset,
1003
139
        "invalid syntax. Perhaps you forgot a comma?"
1004
139
    );
1005
144
}
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
63
{
1022
63
    int nested = 0;
1023
4.69k
    for (int i = p->mark - 1; i >= 0; i--) {
1024
4.69k
        int type = p->tokens[i]->type;
1025
4.69k
        if (type == FSTRING_END || type == TSTRING_END) {
1026
454
            nested++;
1027
454
        }
1028
4.23k
        else if (type == FSTRING_START || type == TSTRING_START) {
1029
517
            if (nested == 0) {
1030
63
                return type == TSTRING_START ? 't' : 'f';
1031
63
            }
1032
454
            nested--;
1033
454
        }
1034
4.69k
    }
1035
63
    Py_UNREACHABLE();
1036
63
}
1037
1038
ResultTokenWithMetadata *
1039
_PyPegen_check_fstring_conversion(Parser *p, Token* conv_token, expr_ty conv)
1040
2.16k
{
1041
2.16k
    if (conv_token->lineno != conv->lineno || conv_token->end_col_offset != conv->col_offset) {
1042
27
        return RAISE_SYNTAX_ERROR_KNOWN_RANGE(
1043
27
            conv_token, conv,
1044
27
            "%c-string: conversion type must come right after the exclamation mark",
1045
27
            formatted_string_prefix(p)
1046
27
        );
1047
27
    }
1048
1049
2.13k
    Py_UCS4 first = PyUnicode_READ_CHAR(conv->v.Name.id, 0);
1050
2.13k
    if (PyUnicode_GET_LENGTH(conv->v.Name.id) > 1 ||
1051
2.12k
            !(first == 's' || first == 'r' || first == 'a')) {
1052
36
        RAISE_SYNTAX_ERROR_KNOWN_LOCATION(conv,
1053
36
                                            "%c-string: invalid conversion character %R: expected 's', 'r', or 'a'",
1054
36
                                            formatted_string_prefix(p),
1055
36
                                            conv->v.Name.id);
1056
36
        return NULL;
1057
36
    }
1058
1059
2.09k
    return result_token_with_metadata(p, conv, conv_token->metadata);
1060
2.13k
}
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
7.02k
{
1066
7.02k
    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
7.02k
    Py_ssize_t n_items = asdl_seq_LEN(spec);
1074
7.02k
    Py_ssize_t non_empty_count = 0;
1075
18.5k
    for (Py_ssize_t i = 0; i < n_items; i++) {
1076
11.5k
        expr_ty item = asdl_seq_GET(spec, i);
1077
11.5k
        non_empty_count += !(item->kind == Constant_kind &&
1078
11.5k
                             PyUnicode_CheckExact(item->v.Constant.value) &&
1079
8.01k
                             PyUnicode_GET_LENGTH(item->v.Constant.value) == 0);
1080
11.5k
    }
1081
7.02k
    if (non_empty_count != n_items) {
1082
3.22k
        asdl_expr_seq *resized_spec =
1083
3.22k
            _Py_asdl_expr_seq_new(non_empty_count, p->arena);
1084
3.22k
        if (resized_spec == NULL) {
1085
0
            return NULL;
1086
0
        }
1087
3.22k
        Py_ssize_t j = 0;
1088
8.19k
        for (Py_ssize_t i = 0; i < n_items; i++) {
1089
4.97k
            expr_ty item = asdl_seq_GET(spec, i);
1090
4.97k
            if (item->kind == Constant_kind &&
1091
4.97k
                PyUnicode_CheckExact(item->v.Constant.value) &&
1092
3.92k
                PyUnicode_GET_LENGTH(item->v.Constant.value) == 0) {
1093
3.22k
                continue;
1094
3.22k
            }
1095
1.75k
            asdl_seq_SET(resized_spec, j++, item);
1096
1.75k
        }
1097
3.22k
        assert(j == non_empty_count);
1098
3.22k
        spec = resized_spec;
1099
3.22k
    }
1100
7.02k
    expr_ty res;
1101
7.02k
    Py_ssize_t n = asdl_seq_LEN(spec);
1102
7.02k
    if (n == 0 || (n == 1 && asdl_seq_GET(spec, 0)->kind == Constant_kind)) {
1103
6.34k
        res = _PyAST_JoinedStr(spec, lineno, col_offset, end_lineno,
1104
6.34k
                                    end_col_offset, p->arena);
1105
6.34k
    } else {
1106
678
        res = _PyPegen_concatenate_strings(p, spec,
1107
678
                             lineno, col_offset, end_lineno,
1108
678
                             end_col_offset, arena);
1109
678
    }
1110
7.02k
    if (!res) {
1111
0
        return NULL;
1112
0
    }
1113
7.02k
    return result_token_with_metadata(p, res, colon->metadata);
1114
7.02k
}
1115
1116
const char *
1117
_PyPegen_get_expr_name(expr_ty e)
1118
232
{
1119
232
    assert(e != NULL);
1120
232
    switch (e->kind) {
1121
1
        case Attribute_kind:
1122
1
            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
3
        case Lambda_kind:
1134
3
            return "lambda";
1135
10
        case Call_kind:
1136
10
            return "function call";
1137
2
        case BoolOp_kind:
1138
48
        case BinOp_kind:
1139
53
        case UnaryOp_kind:
1140
53
            return "expression";
1141
1
        case GeneratorExp_kind:
1142
1
            return "generator expression";
1143
1
        case Yield_kind:
1144
1
        case YieldFrom_kind:
1145
1
            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
2
        case Set_kind:
1157
2
            return "set display";
1158
11
        case JoinedStr_kind:
1159
11
        case FormattedValue_kind:
1160
11
            return "f-string expression";
1161
3
        case TemplateStr_kind:
1162
3
        case Interpolation_kind:
1163
3
            return "t-string expression";
1164
106
        case Constant_kind: {
1165
106
            PyObject *value = e->v.Constant.value;
1166
106
            if (value == Py_None) {
1167
2
                return "None";
1168
2
            }
1169
104
            if (value == Py_False) {
1170
1
                return "False";
1171
1
            }
1172
103
            if (value == Py_True) {
1173
1
                return "True";
1174
1
            }
1175
102
            if (value == Py_Ellipsis) {
1176
1
                return "ellipsis";
1177
1
            }
1178
101
            return "literal";
1179
102
        }
1180
16
        case Compare_kind:
1181
16
            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
232
    }
1192
232
}
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
10
        return comprehension->iter;
1198
10
    }
1199
6
    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
24.1k
                     int end_col_offset, PyArena *arena) {
1205
24.1k
    Py_ssize_t args_len = asdl_seq_LEN(a);
1206
24.1k
    Py_ssize_t total_len = args_len;
1207
1208
24.1k
    if (b == NULL) {
1209
21.9k
        return _PyAST_Call(_PyPegen_dummy_name(p), a, NULL, lineno, col_offset,
1210
21.9k
                        end_lineno, end_col_offset, arena);
1211
1212
21.9k
    }
1213
1214
2.24k
    asdl_expr_seq *starreds = _PyPegen_seq_extract_starred_exprs(p, b);
1215
2.24k
    if (!starreds && PyErr_Occurred()) {
1216
0
        return NULL;
1217
0
    }
1218
1219
2.24k
    asdl_keyword_seq *keywords = _PyPegen_seq_delete_starred_exprs(p, b);
1220
2.24k
    if (!keywords && PyErr_Occurred()) {
1221
0
        return NULL;
1222
0
    }
1223
1224
2.24k
    if (starreds) {
1225
306
        total_len += asdl_seq_LEN(starreds);
1226
306
    }
1227
1228
2.24k
    asdl_expr_seq *args = _Py_asdl_expr_seq_new(total_len, arena);
1229
2.24k
    if (args == NULL) {
1230
0
        return NULL;
1231
0
    }
1232
1233
2.24k
    Py_ssize_t i = 0;
1234
4.86k
    for (i = 0; i < args_len; i++) {
1235
2.61k
        asdl_seq_SET(args, i, asdl_seq_GET(a, i));
1236
2.61k
    }
1237
2.88k
    for (; i < total_len; i++) {
1238
634
        asdl_seq_SET(args, i, asdl_seq_GET(starreds, i - args_len));
1239
634
    }
1240
1241
2.24k
    return _PyAST_Call(_PyPegen_dummy_name(p), args, keywords, lineno,
1242
2.24k
                       col_offset, end_lineno, end_col_offset, arena);
1243
2.24k
}
1244
1245
// AST Error reporting helpers
1246
1247
expr_ty
1248
_PyPegen_get_invalid_target(expr_ty e, TARGETS_TYPE targets_type)
1249
346k
{
1250
346k
    if (e == NULL) {
1251
0
        return NULL;
1252
0
    }
1253
1254
346k
    if (targets_type == SINGLE_TARGETS ||
1255
242k
        targets_type == ATTRIBUTE_OR_SUBSCRIPT_TARGETS) {
1256
210k
        if (targets_type == SINGLE_TARGETS && e->kind == Name_kind) {
1257
62.9k
            return NULL;
1258
62.9k
        }
1259
147k
        return e->kind == Attribute_kind || e->kind == Subscript_kind ? NULL : e;
1260
210k
    }
1261
1262
136k
#define VISIT_CONTAINER(CONTAINER, TYPE) do { \
1263
7.03k
        Py_ssize_t len = asdl_seq_LEN((CONTAINER)->v.TYPE.elts);\
1264
11.5k
        for (Py_ssize_t i = 0; i < len; i++) {\
1265
4.98k
            expr_ty other = asdl_seq_GET((CONTAINER)->v.TYPE.elts, i);\
1266
4.98k
            expr_ty child = _PyPegen_get_invalid_target(other, targets_type);\
1267
4.98k
            if (child != NULL) {\
1268
507
                return child;\
1269
507
            }\
1270
4.98k
        }\
1271
7.03k
    } 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
136k
    switch (e->kind) {
1280
1.51k
        case List_kind:
1281
1.51k
            VISIT_CONTAINER(e, List);
1282
1.34k
            return NULL;
1283
5.52k
        case Tuple_kind:
1284
5.52k
            VISIT_CONTAINER(e, Tuple);
1285
5.18k
            return NULL;
1286
878
        case Starred_kind:
1287
878
            if (targets_type == DEL_TARGETS) {
1288
6
                return e;
1289
6
            }
1290
872
            return _PyPegen_get_invalid_target(e->v.Starred.value, targets_type);
1291
957
        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
957
            if (targets_type == FOR_TARGETS) {
1296
840
                cmpop_ty cmpop = (cmpop_ty) asdl_seq_GET(e->v.Compare.ops, 0);
1297
840
                if (cmpop == In) {
1298
262
                    return _PyPegen_get_invalid_target(e->v.Compare.left, targets_type);
1299
262
                }
1300
578
                return NULL;
1301
840
            }
1302
117
            return e;
1303
84.1k
        case Name_kind:
1304
85.2k
        case Subscript_kind:
1305
87.6k
        case Attribute_kind:
1306
87.6k
            return NULL;
1307
39.6k
        default:
1308
39.6k
            return e;
1309
136k
    }
1310
136k
}
1311
1312
32
void *_PyPegen_arguments_parsing_error(Parser *p, expr_ty e) {
1313
32
    int kwarg_unpacking = 0;
1314
897
    for (Py_ssize_t i = 0, l = asdl_seq_LEN(e->v.Call.keywords); i < l; i++) {
1315
865
        keyword_ty keyword = asdl_seq_GET(e->v.Call.keywords, i);
1316
865
        if (!keyword->arg) {
1317
542
            kwarg_unpacking = 1;
1318
542
        }
1319
865
    }
1320
1321
32
    const char *msg = NULL;
1322
32
    if (kwarg_unpacking) {
1323
20
        msg = "positional argument follows keyword argument unpacking";
1324
20
    } else {
1325
12
        msg = "positional argument follows keyword argument";
1326
12
    }
1327
1328
32
    return RAISE_SYNTAX_ERROR(msg);
1329
32
}
1330
1331
void *
1332
_PyPegen_nonparen_genexp_in_call(Parser *p, expr_ty args, asdl_comprehension_seq *comprehensions)
1333
269
{
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
269
    Py_ssize_t len = asdl_seq_LEN(args->v.Call.args);
1342
269
    if (len <= 1) {
1343
267
        return NULL;
1344
267
    }
1345
1346
2
    comprehension_ty last_comprehension = PyPegen_last_item(comprehensions, comprehension_ty);
1347
1348
2
    return RAISE_SYNTAX_ERROR_KNOWN_RANGE(
1349
269
        (expr_ty) asdl_seq_GET(args->v.Call.args, len - 1),
1350
269
        _PyPegen_get_last_comprehension_item(last_comprehension),
1351
269
        "Generator expression must be parenthesized"
1352
269
    );
1353
269
}
1354
1355
// Fstring stuff
1356
1357
static expr_ty
1358
27.5k
_PyPegen_decode_fstring_part(Parser* p, int is_raw, expr_ty constant, Token* token) {
1359
27.5k
    assert(PyUnicode_CheckExact(constant->v.Constant.value));
1360
1361
27.5k
    const char* bstr = PyUnicode_AsUTF8(constant->v.Constant.value);
1362
27.5k
    if (bstr == NULL) {
1363
0
        return NULL;
1364
0
    }
1365
1366
27.5k
    size_t len;
1367
27.5k
    if (strcmp(bstr, "{{") == 0 || strcmp(bstr, "}}") == 0) {
1368
0
        len = 1;
1369
27.5k
    } else {
1370
27.5k
        len = strlen(bstr);
1371
27.5k
    }
1372
1373
27.5k
    is_raw = is_raw || strchr(bstr, '\\') == NULL;
1374
27.5k
    PyObject *str = _PyPegen_decode_string(p, is_raw, bstr, len, token);
1375
27.5k
    if (str == NULL) {
1376
6
        _Pypegen_raise_decode_error(p);
1377
6
        return NULL;
1378
6
    }
1379
27.5k
    if (_PyArena_AddPyObject(p->arena, str) < 0) {
1380
0
        Py_DECREF(str);
1381
0
        return NULL;
1382
0
    }
1383
27.5k
    return _PyAST_Constant(str, NULL, constant->lineno, constant->col_offset,
1384
27.5k
                           constant->end_lineno, constant->end_col_offset,
1385
27.5k
                           p->arena);
1386
27.5k
}
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
18.2k
{
1392
18.2k
    Py_ssize_t n_items = asdl_seq_LEN(raw_expressions);
1393
18.2k
    Py_ssize_t total_items = n_items;
1394
65.5k
    for (Py_ssize_t i = 0; i < n_items; i++) {
1395
47.3k
        expr_ty item = asdl_seq_GET(raw_expressions, i);
1396
47.3k
        if (item->kind == JoinedStr_kind) {
1397
6.93k
            total_items += asdl_seq_LEN(item->v.JoinedStr.values) - 1;
1398
6.93k
        }
1399
47.3k
    }
1400
1401
18.2k
    const char* quote_str = PyBytes_AsString(a->bytes);
1402
18.2k
    if (quote_str == NULL) {
1403
0
        return NULL;
1404
0
    }
1405
18.2k
    int is_raw = strpbrk(quote_str, "rR") != NULL;
1406
1407
18.2k
    asdl_expr_seq *seq = _Py_asdl_expr_seq_new(total_items, p->arena);
1408
18.2k
    if (seq == NULL) {
1409
0
        return NULL;
1410
0
    }
1411
1412
18.2k
    Py_ssize_t index = 0;
1413
65.5k
    for (Py_ssize_t i = 0; i < n_items; i++) {
1414
47.3k
        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
47.3k
        if (item->kind == JoinedStr_kind) {
1419
6.93k
            asdl_expr_seq *values = item->v.JoinedStr.values;
1420
6.93k
            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
6.93k
            expr_ty first = asdl_seq_GET(values, 0);
1430
6.93k
            assert(first->kind == Constant_kind);
1431
6.93k
            asdl_seq_SET(seq, index++, first);
1432
1433
6.93k
            expr_ty second = asdl_seq_GET(values, 1);
1434
6.93k
            assert((is_tstring &&
1435
6.93k
                    second->kind == Interpolation_kind) ||
1436
6.93k
                   second->kind == FormattedValue_kind);
1437
6.93k
            asdl_seq_SET(seq, index++, second);
1438
1439
6.93k
            continue;
1440
6.93k
        }
1441
1442
40.3k
        if (item->kind == Constant_kind) {
1443
27.5k
            item = _PyPegen_decode_fstring_part(p, is_raw, item, b);
1444
27.5k
            if (item == NULL) {
1445
6
                return NULL;
1446
6
            }
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
27.5k
            if (PyUnicode_CheckExact(item->v.Constant.value)
1452
27.5k
                && PyUnicode_GET_LENGTH(item->v.Constant.value) == 0) {
1453
629
                continue;
1454
629
            }
1455
27.5k
        }
1456
39.7k
        asdl_seq_SET(seq, index++, item);
1457
39.7k
    }
1458
1459
18.2k
    asdl_expr_seq *resized_exprs;
1460
18.2k
    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.61k
        for (Py_ssize_t i = 0; i < index; i++) {
1466
1.98k
            asdl_seq_SET(resized_exprs, i, asdl_seq_GET(seq, i));
1467
1.98k
        }
1468
629
    }
1469
17.5k
    else {
1470
17.5k
        resized_exprs = seq;
1471
17.5k
    }
1472
18.2k
    return resized_exprs;
1473
18.2k
}
1474
1475
expr_ty
1476
3.06k
_PyPegen_template_str(Parser *p, Token *a, asdl_expr_seq *raw_expressions, Token *b) {
1477
1478
3.06k
    asdl_expr_seq *resized_exprs = _get_resized_exprs(p, a, raw_expressions, b, 1);
1479
3.06k
    if (resized_exprs == NULL) {
1480
2
        return NULL;
1481
2
    }
1482
3.06k
    return _PyAST_TemplateStr(resized_exprs, a->lineno, a->col_offset,
1483
3.06k
                              b->end_lineno, b->end_col_offset,
1484
3.06k
                              p->arena);
1485
3.06k
}
1486
1487
expr_ty
1488
15.1k
_PyPegen_joined_str(Parser *p, Token* a, asdl_expr_seq* raw_expressions, Token*b) {
1489
1490
15.1k
    asdl_expr_seq *resized_exprs = _get_resized_exprs(p, a, raw_expressions, b, 0);
1491
15.1k
    if (resized_exprs == NULL) {
1492
4
        return NULL;
1493
4
    }
1494
15.1k
    return _PyAST_JoinedStr(resized_exprs, a->lineno, a->col_offset,
1495
15.1k
                            b->end_lineno, b->end_col_offset,
1496
15.1k
                            p->arena);
1497
15.1k
}
1498
1499
8.26k
expr_ty _PyPegen_decoded_constant_from_token(Parser* p, Token* tok) {
1500
8.26k
    Py_ssize_t bsize;
1501
8.26k
    char* bstr;
1502
8.26k
    if (PyBytes_AsStringAndSize(tok->bytes, &bstr, &bsize) == -1) {
1503
0
        return NULL;
1504
0
    }
1505
1506
8.26k
    int is_raw = tok->is_raw;
1507
1508
8.26k
    PyObject* str = _PyPegen_decode_string(p, is_raw, bstr, bsize, tok);
1509
8.26k
    if (str == NULL) {
1510
5
        return NULL;
1511
5
    }
1512
8.25k
    if (_PyArena_AddPyObject(p->arena, str) < 0) {
1513
0
        Py_DECREF(str);
1514
0
        return NULL;
1515
0
    }
1516
8.25k
    return _PyAST_Constant(str, NULL, tok->lineno, tok->col_offset,
1517
8.25k
                           tok->end_lineno, tok->end_col_offset,
1518
8.25k
                           p->arena);
1519
8.25k
}
1520
1521
31.8k
expr_ty _PyPegen_constant_from_token(Parser* p, Token* tok) {
1522
31.8k
    const char* bstr = PyBytes_AsString(tok->bytes);
1523
31.8k
    if (bstr == NULL) {
1524
0
        return NULL;
1525
0
    }
1526
31.8k
    PyObject* str = PyUnicode_FromString(bstr);
1527
31.8k
    if (str == NULL) {
1528
0
        return NULL;
1529
0
    }
1530
31.8k
    if (_PyArena_AddPyObject(p->arena, str) < 0) {
1531
0
        Py_DECREF(str);
1532
0
        return NULL;
1533
0
    }
1534
31.8k
    return _PyAST_Constant(str, NULL, tok->lineno, tok->col_offset,
1535
31.8k
                           tok->end_lineno, tok->end_col_offset,
1536
31.8k
                           p->arena);
1537
31.8k
}
1538
1539
52.8k
expr_ty _PyPegen_constant_from_string(Parser* p, Token* tok) {
1540
52.8k
    const char* the_str = PyBytes_AsString(tok->bytes);
1541
52.8k
    if (the_str == NULL) {
1542
0
        return NULL;
1543
0
    }
1544
52.8k
    PyObject *s = _PyPegen_parse_string(p, tok);
1545
52.8k
    if (s == NULL) {
1546
119
        _Pypegen_raise_decode_error(p);
1547
119
        return NULL;
1548
119
    }
1549
52.7k
    if (_PyArena_AddPyObject(p->arena, s) < 0) {
1550
0
        Py_DECREF(s);
1551
0
        return NULL;
1552
0
    }
1553
52.7k
    PyObject *kind = NULL;
1554
52.7k
    if (the_str && the_str[0] == 'u') {
1555
2.68k
        kind = _PyPegen_new_identifier(p, "u");
1556
2.68k
        if (kind == NULL) {
1557
0
            return NULL;
1558
0
        }
1559
2.68k
    }
1560
52.7k
    return _PyAST_Constant(s, kind, tok->lineno, tok->col_offset, tok->end_lineno, tok->end_col_offset, p->arena);
1561
52.7k
}
1562
1563
static int
1564
_get_interpolation_conversion(Parser *p, Token *debug, ResultTokenWithMetadata *conversion,
1565
                              ResultTokenWithMetadata *format)
1566
26.9k
{
1567
26.9k
    if (conversion != NULL) {
1568
2.07k
        expr_ty conversion_expr = (expr_ty) conversion->result;
1569
2.07k
        assert(conversion_expr->kind == Name_kind);
1570
2.07k
        Py_UCS4 first = PyUnicode_READ_CHAR(conversion_expr->v.Name.id, 0);
1571
2.07k
        return Py_SAFE_DOWNCAST(first, Py_UCS4, int);
1572
2.07k
    }
1573
24.8k
    else if (debug && !format) {
1574
        /* If no conversion is specified, use !r for debug expressions */
1575
7.68k
        return (int)'r';
1576
7.68k
    }
1577
17.1k
    return -1;
1578
26.9k
}
1579
1580
static PyObject *
1581
_strip_interpolation_debug_expr(PyObject *exprstr)
1582
1.98k
{
1583
1.98k
    Py_ssize_t len = PyUnicode_GET_LENGTH(exprstr);
1584
1585
    /* Discard whitespace and explicit line continuations after the debug "="
1586
       but preserve whitespace before it. */
1587
2.39k
    while (len > 0) {
1588
2.39k
        int has_newline = 0;
1589
5.21k
        while (len > 0) {
1590
5.21k
            Py_UCS4 c = PyUnicode_READ_CHAR(exprstr, len - 1);
1591
5.21k
            if (!_PyUnicode_IsWhitespace(c)) {
1592
2.39k
                break;
1593
2.39k
            }
1594
2.82k
            if (c == '\r' || c == '\n') {
1595
1.75k
                has_newline = 1;
1596
1.75k
            }
1597
2.82k
            len--;
1598
2.82k
        }
1599
2.39k
        if (!has_newline || len == 0 ||
1600
886
            PyUnicode_READ_CHAR(exprstr, len - 1) != '\\')
1601
1.98k
        {
1602
1.98k
            break;
1603
1.98k
        }
1604
408
        len--;
1605
408
    }
1606
1607
    /* Preserve unexpected metadata instead of dropping source text. */
1608
1.98k
    if (len == 0 || PyUnicode_READ_CHAR(exprstr, len - 1) != '=') {
1609
0
        return Py_NewRef(exprstr);
1610
0
    }
1611
1612
1.98k
    return PyUnicode_Substring(exprstr, 0, len - 1);
1613
1.98k
}
1614
1615
expr_ty _PyPegen_interpolation(Parser *p, expr_ty expression, Token *debug, ResultTokenWithMetadata *conversion,
1616
                                 ResultTokenWithMetadata *format, Token *closing_brace, int lineno, int col_offset,
1617
6.48k
                                 int end_lineno, int end_col_offset, PyArena *arena) {
1618
1619
6.48k
    int conversion_val = _get_interpolation_conversion(p, debug, conversion, format);
1620
1621
    /* Find the non whitespace token after the "=" */
1622
6.48k
    int debug_end_line, debug_end_offset;
1623
6.48k
    PyObject *debug_metadata;
1624
6.48k
    constant exprstr;
1625
1626
6.48k
    if (conversion) {
1627
283
        debug_end_line = ((expr_ty) conversion->result)->lineno;
1628
283
        debug_end_offset = ((expr_ty) conversion->result)->col_offset;
1629
283
        debug_metadata = exprstr = conversion->metadata;
1630
283
    }
1631
6.20k
    else if (format) {
1632
1.53k
        debug_end_line = ((expr_ty) format->result)->lineno;
1633
1.53k
        debug_end_offset = ((expr_ty) format->result)->col_offset + 1;
1634
1.53k
        debug_metadata = exprstr = format->metadata;
1635
1.53k
    }
1636
4.66k
    else {
1637
4.66k
        debug_end_line = end_lineno;
1638
4.66k
        debug_end_offset = end_col_offset;
1639
4.66k
        debug_metadata = exprstr = closing_brace->metadata;
1640
4.66k
    }
1641
1642
6.48k
    assert(exprstr != NULL);
1643
6.48k
    PyObject *final_exprstr = debug
1644
6.48k
        ? _strip_interpolation_debug_expr(exprstr)
1645
6.48k
        : Py_NewRef(exprstr);
1646
6.48k
    if (!final_exprstr || _PyArena_AddPyObject(arena, final_exprstr) < 0) {
1647
0
        Py_XDECREF(final_exprstr);
1648
0
        return NULL;
1649
0
    }
1650
1651
6.48k
    expr_ty interpolation = _PyAST_Interpolation(
1652
6.48k
        expression, final_exprstr, conversion_val, format ? (expr_ty) format->result : NULL,
1653
6.48k
        lineno, col_offset, end_lineno,
1654
6.48k
        end_col_offset, arena
1655
6.48k
    );
1656
1657
6.48k
    if (!interpolation || !debug) {
1658
4.50k
        return interpolation;
1659
4.50k
    }
1660
1661
1.98k
    expr_ty debug_text = _PyAST_Constant(debug_metadata, NULL, lineno, col_offset + 1, debug_end_line,
1662
1.98k
                                            debug_end_offset - 1, p->arena);
1663
1.98k
    if (!debug_text) {
1664
0
        return NULL;
1665
0
    }
1666
1667
1.98k
    asdl_expr_seq *values = _Py_asdl_expr_seq_new(2, arena);
1668
1.98k
    if (!values) {
1669
0
        return NULL;
1670
0
    }
1671
1.98k
    asdl_seq_SET(values, 0, debug_text);
1672
1.98k
    asdl_seq_SET(values, 1, interpolation);
1673
1.98k
    return _PyAST_JoinedStr(values, lineno, col_offset, debug_end_line, debug_end_offset, p->arena);
1674
1.98k
}
1675
1676
expr_ty _PyPegen_formatted_value(Parser *p, expr_ty expression, Token *debug, ResultTokenWithMetadata *conversion,
1677
                                 ResultTokenWithMetadata *format, Token *closing_brace, int lineno, int col_offset,
1678
20.4k
                                 int end_lineno, int end_col_offset, PyArena *arena) {
1679
20.4k
    int conversion_val = _get_interpolation_conversion(p, debug, conversion, format);
1680
1681
20.4k
    expr_ty formatted_value = _PyAST_FormattedValue(
1682
20.4k
        expression, conversion_val, format ? (expr_ty) format->result : NULL,
1683
20.4k
        lineno, col_offset, end_lineno,
1684
20.4k
        end_col_offset, arena
1685
20.4k
    );
1686
1687
20.4k
    if (!formatted_value || !debug) {
1688
13.5k
        return formatted_value;
1689
13.5k
    }
1690
1691
    /* Find the non whitespace token after the "=" */
1692
6.88k
    int debug_end_line, debug_end_offset;
1693
6.88k
    PyObject *debug_metadata;
1694
1695
6.88k
    if (conversion) {
1696
198
        debug_end_line = ((expr_ty) conversion->result)->lineno;
1697
198
        debug_end_offset = ((expr_ty) conversion->result)->col_offset;
1698
198
        debug_metadata = conversion->metadata;
1699
198
    }
1700
6.69k
    else if (format) {
1701
260
        debug_end_line = ((expr_ty) format->result)->lineno;
1702
260
        debug_end_offset = ((expr_ty) format->result)->col_offset + 1;
1703
260
        debug_metadata = format->metadata;
1704
260
    }
1705
6.43k
    else {
1706
6.43k
        debug_end_line = end_lineno;
1707
6.43k
        debug_end_offset = end_col_offset;
1708
6.43k
        debug_metadata = closing_brace->metadata;
1709
6.43k
    }
1710
6.88k
    expr_ty debug_text = _PyAST_Constant(debug_metadata, NULL, lineno, col_offset + 1, debug_end_line,
1711
6.88k
                                            debug_end_offset - 1, p->arena);
1712
6.88k
    if (!debug_text) {
1713
0
        return NULL;
1714
0
    }
1715
1716
6.88k
    asdl_expr_seq *values = _Py_asdl_expr_seq_new(2, arena);
1717
6.88k
    if (!values) {
1718
0
        return NULL;
1719
0
    }
1720
6.88k
    asdl_seq_SET(values, 0, debug_text);
1721
6.88k
    asdl_seq_SET(values, 1, formatted_value);
1722
6.88k
    return _PyAST_JoinedStr(values, lineno, col_offset, debug_end_line, debug_end_offset, p->arena);
1723
6.88k
}
1724
1725
static expr_ty
1726
_build_concatenated_bytes(Parser *p, asdl_expr_seq *strings, int lineno,
1727
                        int col_offset, int end_lineno, int end_col_offset,
1728
                        PyArena *arena)
1729
716
{
1730
716
    Py_ssize_t len = asdl_seq_LEN(strings);
1731
716
    assert(len > 0);
1732
1733
    /* Bytes literals never get a kind, but just for consistency
1734
        since they are represented as Constant nodes, we'll mirror
1735
        the same behavior as unicode strings for determining the
1736
        kind. */
1737
716
    PyObject *kind = asdl_seq_GET(strings, 0)->v.Constant.kind;
1738
1739
716
    Py_ssize_t total = 0;
1740
3.38k
    for (Py_ssize_t i = 0; i < len; i++) {
1741
2.66k
        expr_ty elem = asdl_seq_GET(strings, i);
1742
2.66k
        PyObject *bytes = elem->v.Constant.value;
1743
2.66k
        Py_ssize_t part = PyBytes_GET_SIZE(bytes);
1744
2.66k
        if (part > PY_SSIZE_T_MAX - total) {
1745
0
            PyErr_NoMemory();
1746
0
            return NULL;
1747
0
        }
1748
2.66k
        total += part;
1749
2.66k
    }
1750
1751
716
    PyBytesWriter *writer = PyBytesWriter_Create(total);
1752
716
    if (writer == NULL) {
1753
0
        return NULL;
1754
0
    }
1755
716
    char *out = PyBytesWriter_GetData(writer);
1756
1757
3.38k
    for (Py_ssize_t i = 0; i < len; i++) {
1758
2.66k
        expr_ty elem = asdl_seq_GET(strings, i);
1759
2.66k
        PyObject *bytes = elem->v.Constant.value;
1760
2.66k
        Py_ssize_t part = PyBytes_GET_SIZE(bytes);
1761
2.66k
        if (part > 0) {
1762
1.02k
            memcpy(out, PyBytes_AS_STRING(bytes), part);
1763
1.02k
            out += part;
1764
1.02k
        }
1765
2.66k
    }
1766
1767
716
    PyObject *res = PyBytesWriter_Finish(writer);
1768
716
    if (res == NULL) {
1769
0
        return NULL;
1770
0
    }
1771
716
    if (_PyArena_AddPyObject(arena, res) < 0) {
1772
0
        Py_DECREF(res);
1773
0
        return NULL;
1774
0
    }
1775
716
    return _PyAST_Constant(res, kind, lineno, col_offset, end_lineno, end_col_offset, p->arena);
1776
716
}
1777
1778
static expr_ty
1779
_build_concatenated_unicode(Parser *p, asdl_expr_seq *strings, int lineno,
1780
                        int col_offset, int end_lineno, int end_col_offset,
1781
                        PyArena *arena)
1782
1.66k
{
1783
1.66k
    Py_ssize_t len = asdl_seq_LEN(strings);
1784
1.66k
    assert(len > 1);
1785
1786
1.66k
    expr_ty first = asdl_seq_GET(strings, 0);
1787
1788
    /* When a string is getting concatenated, the kind of the string
1789
        is determined by the first string in the concatenation
1790
        sequence.
1791
1792
        u"abc" "def" -> u"abcdef"
1793
        "abc" u"abc" ->  "abcabc" */
1794
1.66k
    PyObject *kind = first->v.Constant.kind;
1795
1796
1.66k
    PyUnicodeWriter *writer = PyUnicodeWriter_Create(0);
1797
1.66k
    if (writer == NULL) {
1798
0
        return NULL;
1799
0
    }
1800
1801
23.6k
    for (Py_ssize_t i = 0; i < len; i++) {
1802
21.9k
        expr_ty current_elem = asdl_seq_GET(strings, i);
1803
21.9k
        assert(current_elem->kind == Constant_kind);
1804
1805
21.9k
        if (PyUnicodeWriter_WriteStr(writer,
1806
21.9k
                                     current_elem->v.Constant.value)) {
1807
0
            PyUnicodeWriter_Discard(writer);
1808
0
            return NULL;
1809
0
        }
1810
21.9k
    }
1811
1812
1.66k
    PyObject *final = PyUnicodeWriter_Finish(writer);
1813
1.66k
    if (final == NULL) {
1814
0
        return NULL;
1815
0
    }
1816
1.66k
    if (_PyArena_AddPyObject(p->arena, final) < 0) {
1817
0
        Py_DECREF(final);
1818
0
        return NULL;
1819
0
    }
1820
1.66k
    return _PyAST_Constant(final, kind, lineno, col_offset,
1821
1.66k
                           end_lineno, end_col_offset, arena);
1822
1.66k
}
1823
1824
static asdl_expr_seq *
1825
_build_concatenated_str(Parser *p, asdl_expr_seq *strings,
1826
                               int lineno, int col_offset, int end_lineno,
1827
                               int end_col_offset, PyArena *arena)
1828
12.7k
{
1829
12.7k
    Py_ssize_t len = asdl_seq_LEN(strings);
1830
12.7k
    assert(len > 0);
1831
1832
12.7k
    Py_ssize_t n_flattened_elements = 0;
1833
38.2k
    for (Py_ssize_t i = 0; i < len; i++) {
1834
25.5k
        expr_ty elem = asdl_seq_GET(strings, i);
1835
25.5k
        switch(elem->kind) {
1836
12.9k
            case JoinedStr_kind:
1837
12.9k
                n_flattened_elements += asdl_seq_LEN(elem->v.JoinedStr.values);
1838
12.9k
                break;
1839
2.59k
            case TemplateStr_kind:
1840
2.59k
                n_flattened_elements += asdl_seq_LEN(elem->v.TemplateStr.values);
1841
2.59k
                break;
1842
9.96k
            default:
1843
9.96k
                n_flattened_elements++;
1844
9.96k
                break;
1845
25.5k
        }
1846
25.5k
    }
1847
1848
1849
12.7k
    asdl_expr_seq* flattened = _Py_asdl_expr_seq_new(n_flattened_elements, p->arena);
1850
12.7k
    if (flattened == NULL) {
1851
0
        return NULL;
1852
0
    }
1853
1854
    /* build flattened list */
1855
12.7k
    Py_ssize_t current_pos = 0;
1856
38.2k
    for (Py_ssize_t i = 0; i < len; i++) {
1857
25.5k
        expr_ty elem = asdl_seq_GET(strings, i);
1858
25.5k
        switch(elem->kind) {
1859
12.9k
            case JoinedStr_kind:
1860
53.2k
                for (Py_ssize_t j = 0; j < asdl_seq_LEN(elem->v.JoinedStr.values); j++) {
1861
40.2k
                    expr_ty subvalue = asdl_seq_GET(elem->v.JoinedStr.values, j);
1862
40.2k
                    if (subvalue == NULL) {
1863
0
                        return NULL;
1864
0
                    }
1865
40.2k
                    asdl_seq_SET(flattened, current_pos++, subvalue);
1866
40.2k
                }
1867
12.9k
                break;
1868
12.9k
            case TemplateStr_kind:
1869
10.9k
                for (Py_ssize_t j = 0; j < asdl_seq_LEN(elem->v.TemplateStr.values); j++) {
1870
8.38k
                    expr_ty subvalue = asdl_seq_GET(elem->v.TemplateStr.values, j);
1871
8.38k
                    if (subvalue == NULL) {
1872
0
                        return NULL;
1873
0
                    }
1874
8.38k
                    asdl_seq_SET(flattened, current_pos++, subvalue);
1875
8.38k
                }
1876
2.59k
                break;
1877
9.96k
            default:
1878
9.96k
                asdl_seq_SET(flattened, current_pos++, elem);
1879
9.96k
                break;
1880
25.5k
        }
1881
25.5k
    }
1882
1883
    /* calculate folded element count */
1884
12.7k
    Py_ssize_t n_elements = 0;
1885
12.7k
    int prev_is_constant = 0;
1886
71.3k
    for (Py_ssize_t i = 0; i < n_flattened_elements; i++) {
1887
58.6k
        expr_ty elem = asdl_seq_GET(flattened, i);
1888
1889
        /* The concatenation of a FormattedValue and an empty Constant should
1890
           lead to the FormattedValue itself. Thus, we will not take any empty
1891
           constants into account, just as in `_PyPegen_joined_str` */
1892
58.6k
        if (elem->kind == Constant_kind &&
1893
58.6k
            PyUnicode_CheckExact(elem->v.Constant.value) &&
1894
36.4k
            PyUnicode_GET_LENGTH(elem->v.Constant.value) == 0)
1895
1.54k
            continue;
1896
1897
57.0k
        if (!prev_is_constant || elem->kind != Constant_kind) {
1898
46.4k
            n_elements++;
1899
46.4k
        }
1900
57.0k
        prev_is_constant = elem->kind == Constant_kind;
1901
57.0k
    }
1902
1903
12.7k
    asdl_expr_seq* values = _Py_asdl_expr_seq_new(n_elements, p->arena);
1904
12.7k
    if (values == NULL) {
1905
0
        return NULL;
1906
0
    }
1907
1908
    /* build folded list */
1909
12.7k
    current_pos = 0;
1910
59.4k
    for (Py_ssize_t i = 0; i < n_flattened_elements; i++) {
1911
46.7k
        expr_ty elem = asdl_seq_GET(flattened, i);
1912
1913
        /* if the current elem and the following are constants,
1914
           fold them and all consequent constants */
1915
46.7k
        if (elem->kind == Constant_kind) {
1916
24.5k
            if (i + 1 < n_flattened_elements &&
1917
20.5k
                asdl_seq_GET(flattened, i + 1)->kind == Constant_kind) {
1918
3.59k
                expr_ty first_elem = elem;
1919
1920
                /* When a string is getting concatenated, the kind of the string
1921
                   is determined by the first string in the concatenation
1922
                   sequence.
1923
1924
                   u"abc" "def" -> u"abcdef"
1925
                   "abc" u"abc" ->  "abcabc" */
1926
3.59k
                PyObject *kind = elem->v.Constant.kind;
1927
1928
3.59k
                PyUnicodeWriter *writer = PyUnicodeWriter_Create(0);
1929
3.59k
                if (writer == NULL) {
1930
0
                    return NULL;
1931
0
                }
1932
3.59k
                expr_ty last_elem = elem;
1933
3.59k
                Py_ssize_t j;
1934
19.0k
                for (j = i; j < n_flattened_elements; j++) {
1935
17.2k
                    expr_ty current_elem = asdl_seq_GET(flattened, j);
1936
17.2k
                    if (current_elem->kind == Constant_kind) {
1937
15.4k
                        if (PyUnicodeWriter_WriteStr(writer,
1938
15.4k
                                                     current_elem->v.Constant.value)) {
1939
0
                            PyUnicodeWriter_Discard(writer);
1940
0
                            return NULL;
1941
0
                        }
1942
15.4k
                        last_elem = current_elem;
1943
15.4k
                    } else {
1944
1.83k
                        break;
1945
1.83k
                    }
1946
17.2k
                }
1947
3.59k
                i = j - 1;
1948
1949
3.59k
                PyObject *concat_str = PyUnicodeWriter_Finish(writer);
1950
3.59k
                if (concat_str == NULL) {
1951
0
                    return NULL;
1952
0
                }
1953
3.59k
                if (_PyArena_AddPyObject(p->arena, concat_str) < 0) {
1954
0
                    Py_DECREF(concat_str);
1955
0
                    return NULL;
1956
0
                }
1957
3.59k
                elem = _PyAST_Constant(concat_str, kind, first_elem->lineno,
1958
3.59k
                                       first_elem->col_offset,
1959
3.59k
                                       last_elem->end_lineno,
1960
3.59k
                                       last_elem->end_col_offset, p->arena);
1961
3.59k
                if (elem == NULL) {
1962
0
                    return NULL;
1963
0
                }
1964
3.59k
            }
1965
1966
            /* Drop all empty contanst strings */
1967
24.5k
            if (PyUnicode_CheckExact(elem->v.Constant.value) &&
1968
24.5k
                PyUnicode_GET_LENGTH(elem->v.Constant.value) == 0) {
1969
329
                continue;
1970
329
            }
1971
24.5k
        }
1972
1973
46.4k
        asdl_seq_SET(values, current_pos++, elem);
1974
46.4k
    }
1975
1976
12.7k
    assert(current_pos == n_elements);
1977
12.7k
    return values;
1978
12.7k
}
1979
1980
static expr_ty
1981
_build_concatenated_joined_str(Parser *p, asdl_expr_seq *strings,
1982
                               int lineno, int col_offset, int end_lineno,
1983
                               int end_col_offset, PyArena *arena)
1984
10.8k
{
1985
10.8k
    asdl_expr_seq *values = _build_concatenated_str(p, strings, lineno,
1986
10.8k
        col_offset, end_lineno, end_col_offset, arena);
1987
10.8k
    if (!values) {
1988
0
        return NULL;
1989
0
    }
1990
10.8k
    return _PyAST_JoinedStr(values, lineno, col_offset, end_lineno, end_col_offset, p->arena);
1991
10.8k
}
1992
1993
expr_ty
1994
_PyPegen_concatenate_tstrings(Parser *p, asdl_expr_seq *strings,
1995
                               int lineno, int col_offset, int end_lineno,
1996
                               int end_col_offset, PyArena *arena)
1997
1.87k
{
1998
1.87k
    asdl_expr_seq *values = _build_concatenated_str(p, strings, lineno,
1999
1.87k
        col_offset, end_lineno, end_col_offset, arena);
2000
1.87k
    if (!values) {
2001
0
        return NULL;
2002
0
    }
2003
1.87k
    return _PyAST_TemplateStr(values, lineno, col_offset, end_lineno,
2004
1.87k
        end_col_offset, arena);
2005
1.87k
}
2006
2007
expr_ty
2008
_PyPegen_concatenate_strings(Parser *p, asdl_expr_seq *strings,
2009
                             int lineno, int col_offset, int end_lineno,
2010
                             int end_col_offset, PyArena *arena)
2011
28.5k
{
2012
28.5k
    Py_ssize_t len = asdl_seq_LEN(strings);
2013
28.5k
    assert(len > 0);
2014
2015
28.5k
    int f_string_found = 0;
2016
28.5k
    int unicode_string_found = 0;
2017
28.5k
    int bytes_found = 0;
2018
2019
28.5k
    Py_ssize_t i = 0;
2020
91.4k
    for (i = 0; i < len; i++) {
2021
62.9k
        expr_ty elem = asdl_seq_GET(strings, i);
2022
62.9k
        switch(elem->kind) {
2023
46.6k
            case Constant_kind:
2024
46.6k
                if (PyBytes_CheckExact(elem->v.Constant.value)) {
2025
4.49k
                    bytes_found = 1;
2026
42.1k
                } else {
2027
42.1k
                    unicode_string_found = 1;
2028
42.1k
                }
2029
46.6k
                break;
2030
12.9k
            case JoinedStr_kind:
2031
12.9k
                f_string_found = 1;
2032
12.9k
                break;
2033
0
            case TemplateStr_kind:
2034
                // python.gram handles this; we should never get here
2035
0
                assert(0);
2036
0
                break;
2037
3.27k
            default:
2038
3.27k
                f_string_found = 1;
2039
3.27k
                break;
2040
62.9k
        }
2041
62.9k
    }
2042
2043
    // Cannot mix unicode and bytes
2044
28.5k
    if ((unicode_string_found || f_string_found) && bytes_found) {
2045
5
        RAISE_SYNTAX_ERROR("cannot mix bytes and nonbytes literals");
2046
5
        return NULL;
2047
5
    }
2048
2049
    // If it's only bytes or only unicode string, do a simple concat
2050
28.5k
    if (!f_string_found) {
2051
17.6k
        if (len == 1) {
2052
15.3k
            return asdl_seq_GET(strings, 0);
2053
15.3k
        }
2054
2.38k
        else if (bytes_found) {
2055
716
            return _build_concatenated_bytes(p, strings, lineno, col_offset,
2056
716
                end_lineno, end_col_offset, arena);
2057
716
        }
2058
1.66k
        else {
2059
1.66k
            return _build_concatenated_unicode(p, strings, lineno, col_offset,
2060
1.66k
                end_lineno, end_col_offset, arena);
2061
1.66k
        }
2062
17.6k
    }
2063
2064
10.8k
    return _build_concatenated_joined_str(p, strings, lineno,
2065
10.8k
        col_offset, end_lineno, end_col_offset, arena);
2066
28.5k
}
2067
2068
static int
2069
_warn_relative_import_of_lazy(Parser *p, asdl_seq *dots, expr_ty module)
2070
631
{
2071
    // Warn about `from . lazy import x`: the whitespace between the dots and
2072
    // the module name is insignificant, so this is parsed exactly like
2073
    // `from .lazy import x` (an import of the relative module "lazy"), but it
2074
    // is most likely a transposition of `lazy from . import x` (PEP 810).
2075
631
    if (p->call_invalid_rules) {
2076
261
        return 0;
2077
261
    }
2078
2079
    // Only fire if there is whitespace between the last dot and the name,
2080
    // i.e. not for the common `from .lazy import x` spelling.
2081
370
    Token *last_dot = asdl_seq_GET_UNTYPED(dots, asdl_seq_LEN(dots) - 1);
2082
370
    if (
2083
370
        last_dot->end_lineno == module->lineno
2084
370
        && last_dot->end_col_offset == module->col_offset
2085
370
    ) {
2086
149
        return 0;
2087
149
    }
2088
2089
221
    int count = _PyPegen_seq_count_dots(dots);
2090
221
    char *buf = PyMem_RawMalloc(count + 1);
2091
221
    if (buf == NULL) {
2092
0
        PyErr_NoMemory();
2093
0
        return -1;
2094
0
    }
2095
221
    memset(buf, '.', count);
2096
221
    buf[count] = '\0';
2097
2098
221
    PyObject *msg = PyUnicode_FromFormat(
2099
221
        "'from %s lazy import' is the same as 'from %slazy import'; "
2100
221
        "did you mean 'lazy from %s import'?",
2101
221
        buf, buf, buf);
2102
221
    PyMem_RawFree(buf);
2103
221
    if (msg == NULL) {
2104
0
        return -1;
2105
0
    }
2106
2107
221
    _PyTokenizer_Info info = _PyTokenizer_GetInfo(p->tok);
2108
221
    int res = _PyErr_EmitSyntaxWarning(msg,
2109
221
                                       info.filename,
2110
221
                                       module->lineno,
2111
221
                                       module->col_offset + 1,
2112
221
                                       module->end_lineno,
2113
221
                                       module->end_col_offset + 1,
2114
221
                                       info.module);
2115
221
    Py_DECREF(msg);
2116
221
    return res;
2117
221
}
2118
2119
stmt_ty
2120
_PyPegen_checked_from_import(Parser *p, asdl_seq *dots, expr_ty module_name,
2121
                             asdl_alias_seq *names, expr_ty lazy_token, int lineno,
2122
                             int col_offset, int end_lineno, int end_col_offset,
2123
                             PyArena *arena)
2124
3.49k
{
2125
3.49k
    identifier module = module_name->v.Name.id;
2126
3.49k
    int level = _PyPegen_seq_count_dots(dots);
2127
3.49k
    if (level == 0 && PyUnicode_CompareWithASCIIString(module, "__future__") == 0) {
2128
828
        if (lazy_token) {
2129
1
            RAISE_SYNTAX_ERROR_KNOWN_LOCATION(lazy_token,
2130
1
                "lazy from __future__ import is not allowed");
2131
1
            return NULL;
2132
1
        }
2133
1.89k
        for (Py_ssize_t i = 0; i < asdl_seq_LEN(names); i++) {
2134
1.06k
            alias_ty alias = asdl_seq_GET(names, i);
2135
1.06k
            if (PyUnicode_CompareWithASCIIString(alias->name, "barry_as_FLUFL") == 0) {
2136
300
                p->flags |= PyPARSE_BARRY_AS_BDFL;
2137
300
                p->tok->barry_as_bdfl = 1;
2138
300
            }
2139
1.06k
        }
2140
827
    }
2141
2.66k
    else if (
2142
2.66k
        level > 0
2143
1.61k
        && lazy_token == NULL
2144
1.58k
        && PyUnicode_CompareWithASCIIString(module, "lazy") == 0
2145
2.66k
    ) {
2146
631
        if (_warn_relative_import_of_lazy(p, dots, module_name) < 0) {
2147
0
            return NULL;
2148
0
        }
2149
631
    }
2150
3.49k
    return _PyAST_ImportFrom(module, names, level, lazy_token ? 1 : 0, lineno,
2151
3.49k
                             col_offset, end_lineno, end_col_offset, arena);
2152
3.49k
}
2153
2154
asdl_stmt_seq*
2155
26.5k
_PyPegen_register_stmts(Parser *p, asdl_stmt_seq* stmts) {
2156
26.5k
    if (!p->call_invalid_rules) {
2157
18.9k
        return stmts;
2158
18.9k
    }
2159
7.54k
    Py_ssize_t len = asdl_seq_LEN(stmts);
2160
7.54k
    if (len == 0) {
2161
0
        return stmts;
2162
0
    }
2163
7.54k
    stmt_ty last_stmt = asdl_seq_GET(stmts, len - 1);
2164
7.54k
    if (p->last_stmt_location.lineno > last_stmt->lineno) {
2165
231
        return stmts;
2166
231
    }
2167
7.30k
    p->last_stmt_location.lineno = last_stmt->lineno;
2168
7.30k
    p->last_stmt_location.col_offset = last_stmt->col_offset;
2169
7.30k
    p->last_stmt_location.end_lineno = last_stmt->end_lineno;
2170
7.30k
    p->last_stmt_location.end_col_offset = last_stmt->end_col_offset;
2171
7.30k
    return stmts;
2172
7.54k
}