Coverage Report

Created: 2026-10-15 06:54

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
#include "lexer/state.h"            // tok_state
10
11
12
void *
13
_PyPegen_dummy_name(Parser *p, ...)
14
114k
{
15
114k
    return &_PyRuntime.parser.dummy_name;
16
114k
}
17
18
/* Creates a single-element asdl_seq* that contains a */
19
asdl_seq *
20
_PyPegen_singleton_seq(Parser *p, void *a)
21
594k
{
22
594k
    assert(a != NULL);
23
594k
    asdl_seq *seq = (asdl_seq*)_Py_asdl_generic_seq_new(1, p->arena);
24
594k
    if (!seq) {
25
0
        return NULL;
26
0
    }
27
594k
    asdl_seq_SET_UNTYPED(seq, 0, a);
28
594k
    return seq;
29
594k
}
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
2.25M
{
35
2.25M
    assert(a != NULL);
36
2.25M
    if (!seq) {
37
308k
        return _PyPegen_singleton_seq(p, a);
38
308k
    }
39
40
1.94M
    asdl_seq *new_seq = (asdl_seq*)_Py_asdl_generic_seq_new(asdl_seq_LEN(seq) + 1, p->arena);
41
1.94M
    if (!new_seq) {
42
0
        return NULL;
43
0
    }
44
45
1.94M
    asdl_seq_SET_UNTYPED(new_seq, 0, a);
46
8.50M
    for (Py_ssize_t i = 1, l = asdl_seq_LEN(new_seq); i < l; i++) {
47
6.56M
        asdl_seq_SET_UNTYPED(new_seq, i, asdl_seq_GET_UNTYPED(seq, i - 1));
48
6.56M
    }
49
1.94M
    return new_seq;
50
1.94M
}
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
39.3k
{
76
39.3k
    Py_ssize_t size = 0;
77
261k
    for (Py_ssize_t i = 0, l = asdl_seq_LEN(seqs); i < l; i++) {
78
222k
        asdl_seq *inner_seq = asdl_seq_GET_UNTYPED(seqs, i);
79
222k
        size += asdl_seq_LEN(inner_seq);
80
222k
    }
81
39.3k
    return size;
82
39.3k
}
83
84
/* Flattens an asdl_seq* of asdl_seq*s */
85
asdl_seq *
86
_PyPegen_seq_flatten(Parser *p, asdl_seq *seqs)
87
39.3k
{
88
39.3k
    Py_ssize_t flattened_seq_size = _get_flattened_seq_size(seqs);
89
39.3k
    assert(flattened_seq_size > 0);
90
91
39.3k
    asdl_seq *flattened_seq = (asdl_seq*)_Py_asdl_generic_seq_new(flattened_seq_size, p->arena);
92
39.3k
    if (!flattened_seq) {
93
0
        return NULL;
94
0
    }
95
96
39.3k
    int flattened_seq_idx = 0;
97
261k
    for (Py_ssize_t i = 0, l = asdl_seq_LEN(seqs); i < l; i++) {
98
222k
        asdl_seq *inner_seq = asdl_seq_GET_UNTYPED(seqs, i);
99
483k
        for (Py_ssize_t j = 0, li = asdl_seq_LEN(inner_seq); j < li; j++) {
100
260k
            asdl_seq_SET_UNTYPED(flattened_seq, flattened_seq_idx++, asdl_seq_GET_UNTYPED(inner_seq, j));
101
260k
        }
102
222k
    }
103
39.3k
    assert(flattened_seq_idx == flattened_seq_size);
104
105
39.3k
    return flattened_seq;
106
39.3k
}
107
108
void *
109
_PyPegen_seq_last_item(asdl_seq *seq)
110
156
{
111
156
    Py_ssize_t len = asdl_seq_LEN(seq);
112
156
    return asdl_seq_GET_UNTYPED(seq, len - 1);
113
156
}
114
115
void *
116
_PyPegen_seq_first_item(asdl_seq *seq)
117
100
{
118
100
    return asdl_seq_GET_UNTYPED(seq, 0);
119
100
}
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
21.2k
{
125
21.2k
    assert(first_name != NULL && second_name != NULL);
126
21.2k
    PyObject *uni = PyUnicode_FromFormat("%U.%U",
127
21.2k
            first_name->v.Name.id, second_name->v.Name.id);
128
21.2k
    if (!uni) {
129
0
        return NULL;
130
0
    }
131
21.2k
    PyInterpreterState *interp = _PyInterpreterState_GET();
132
21.2k
    _PyUnicode_InternImmortal(interp, &uni);
133
21.2k
    if (_PyArena_AddPyObject(p->arena, uni) < 0) {
134
0
        Py_DECREF(uni);
135
0
        return NULL;
136
0
    }
137
138
21.2k
    return _PyAST_Name(uni, Load, EXTRA_EXPR(first_name, second_name));
139
21.2k
}
140
141
/* Counts the total number of dots in seq's tokens */
142
int
143
_PyPegen_seq_count_dots(asdl_seq *seq)
144
9.98k
{
145
9.98k
    int number_of_dots = 0;
146
18.1k
    for (Py_ssize_t i = 0, l = asdl_seq_LEN(seq); i < l; i++) {
147
8.11k
        Token *current_expr = asdl_seq_GET_UNTYPED(seq, i);
148
8.11k
        switch (current_expr->type) {
149
3.24k
            case ELLIPSIS:
150
3.24k
                number_of_dots += 3;
151
3.24k
                break;
152
4.87k
            case DOT:
153
4.87k
                number_of_dots += 1;
154
4.87k
                break;
155
0
            default:
156
0
                Py_UNREACHABLE();
157
8.11k
        }
158
8.11k
    }
159
160
9.98k
    return number_of_dots;
161
9.98k
}
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
118
                        int end_col_offset, PyArena *arena) {
167
118
    PyObject *str = PyUnicode_InternFromString("*");
168
118
    if (!str) {
169
0
        return NULL;
170
0
    }
171
118
    if (_PyArena_AddPyObject(p->arena, str) < 0) {
172
0
        Py_DECREF(str);
173
0
        return NULL;
174
0
    }
175
118
    return _PyAST_alias(str, NULL, lineno, col_offset, end_lineno, end_col_offset, arena);
176
118
}
177
178
/* Creates a new asdl_seq* with the identifiers of all the names in seq */
179
asdl_identifier_seq *
180
_PyPegen_map_names_to_ids(Parser *p, asdl_expr_seq *seq)
181
1.94k
{
182
1.94k
    Py_ssize_t len = asdl_seq_LEN(seq);
183
1.94k
    assert(len > 0);
184
185
1.94k
    asdl_identifier_seq *new_seq = _Py_asdl_identifier_seq_new(len, p->arena);
186
1.94k
    if (!new_seq) {
187
0
        return NULL;
188
0
    }
189
6.42k
    for (Py_ssize_t i = 0; i < len; i++) {
190
4.48k
        expr_ty e = asdl_seq_GET(seq, i);
191
4.48k
        asdl_seq_SET(new_seq, i, e->v.Name.id);
192
4.48k
    }
193
1.94k
    return new_seq;
194
1.94k
}
195
196
/* Constructs a CmpopExprPair */
197
CmpopExprPair *
198
_PyPegen_cmpop_expr_pair(Parser *p, cmpop_ty cmpop, expr_ty expr)
199
334k
{
200
334k
    assert(expr != NULL);
201
334k
    CmpopExprPair *a = _PyArena_Malloc(p->arena, sizeof(CmpopExprPair));
202
334k
    if (!a) {
203
0
        return NULL;
204
0
    }
205
334k
    a->cmpop = cmpop;
206
334k
    a->expr = expr;
207
334k
    return a;
208
334k
}
209
210
asdl_int_seq *
211
_PyPegen_get_cmpops(Parser *p, asdl_seq *seq)
212
48.5k
{
213
48.5k
    Py_ssize_t len = asdl_seq_LEN(seq);
214
48.5k
    assert(len > 0);
215
216
48.5k
    asdl_int_seq *new_seq = _Py_asdl_int_seq_new(len, p->arena);
217
48.5k
    if (!new_seq) {
218
0
        return NULL;
219
0
    }
220
351k
    for (Py_ssize_t i = 0; i < len; i++) {
221
302k
        CmpopExprPair *pair = asdl_seq_GET_UNTYPED(seq, i);
222
302k
        asdl_seq_SET(new_seq, i, pair->cmpop);
223
302k
    }
224
48.5k
    return new_seq;
225
48.5k
}
226
227
asdl_expr_seq *
228
_PyPegen_get_exprs(Parser *p, asdl_seq *seq)
229
48.5k
{
230
48.5k
    Py_ssize_t len = asdl_seq_LEN(seq);
231
48.5k
    assert(len > 0);
232
233
48.5k
    asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena);
234
48.5k
    if (!new_seq) {
235
0
        return NULL;
236
0
    }
237
351k
    for (Py_ssize_t i = 0; i < len; i++) {
238
302k
        CmpopExprPair *pair = asdl_seq_GET_UNTYPED(seq, i);
239
302k
        asdl_seq_SET(new_seq, i, pair->expr);
240
302k
    }
241
48.5k
    return new_seq;
242
48.5k
}
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
8.93k
{
248
8.93k
    Py_ssize_t len = asdl_seq_LEN(seq);
249
8.93k
    if (len == 0) {
250
6.65k
        return NULL;
251
6.65k
    }
252
253
2.27k
    asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena);
254
2.27k
    if (!new_seq) {
255
0
        return NULL;
256
0
    }
257
6.43k
    for (Py_ssize_t i = 0; i < len; i++) {
258
4.15k
        expr_ty e = asdl_seq_GET(seq, i);
259
4.15k
        expr_ty new_e = _PyPegen_set_expr_context(p, e, ctx);
260
4.15k
        if (!new_e) {
261
0
            return NULL;
262
0
        }
263
4.15k
        asdl_seq_SET(new_seq, i, new_e);
264
4.15k
    }
265
2.27k
    return new_seq;
266
2.27k
}
267
268
static expr_ty
269
_set_name_context(Parser *p, expr_ty e, expr_context_ty ctx)
270
701k
{
271
701k
    return _PyAST_Name(e->v.Name.id, ctx, EXTRA_EXPR(e, e));
272
701k
}
273
274
static expr_ty
275
_set_tuple_context(Parser *p, expr_ty e, expr_context_ty ctx)
276
6.28k
{
277
6.28k
    asdl_expr_seq *seq = _set_seq_context(p, e->v.Tuple.elts, ctx);
278
6.28k
    if (!seq && PyErr_Occurred()) {
279
0
        return NULL;
280
0
    }
281
6.28k
    return _PyAST_Tuple(seq, ctx, EXTRA_EXPR(e, e));
282
6.28k
}
283
284
static expr_ty
285
_set_list_context(Parser *p, expr_ty e, expr_context_ty ctx)
286
2.65k
{
287
2.65k
    asdl_expr_seq *seq = _set_seq_context(p, e->v.List.elts, ctx);
288
2.65k
    if (!seq && PyErr_Occurred()) {
289
0
        return NULL;
290
0
    }
291
2.65k
    return _PyAST_List(seq, ctx, EXTRA_EXPR(e, e));
292
2.65k
}
293
294
static expr_ty
295
_set_subscript_context(Parser *p, expr_ty e, expr_context_ty ctx)
296
23.4k
{
297
23.4k
    return _PyAST_Subscript(e->v.Subscript.value, e->v.Subscript.slice,
298
23.4k
                            ctx, EXTRA_EXPR(e, e));
299
23.4k
}
300
301
static expr_ty
302
_set_attribute_context(Parser *p, expr_ty e, expr_context_ty ctx)
303
40.2k
{
304
40.2k
    return _PyAST_Attribute(e->v.Attribute.value, e->v.Attribute.attr,
305
40.2k
                            ctx, EXTRA_EXPR(e, e));
306
40.2k
}
307
308
static expr_ty
309
_set_starred_context(Parser *p, expr_ty e, expr_context_ty ctx)
310
237
{
311
237
    expr_ty inner = _PyPegen_set_expr_context(p, e->v.Starred.value, ctx);
312
237
    if (!inner) {
313
0
        return NULL;
314
0
    }
315
237
    return _PyAST_Starred(inner, ctx, EXTRA_EXPR(e, e));
316
237
}
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
774k
{
322
774k
    assert(expr != NULL);
323
324
774k
    expr_ty new = NULL;
325
774k
    switch (expr->kind) {
326
701k
        case Name_kind:
327
701k
            new = _set_name_context(p, expr, ctx);
328
701k
            break;
329
6.28k
        case Tuple_kind:
330
6.28k
            new = _set_tuple_context(p, expr, ctx);
331
6.28k
            break;
332
2.65k
        case List_kind:
333
2.65k
            new = _set_list_context(p, expr, ctx);
334
2.65k
            break;
335
23.4k
        case Subscript_kind:
336
23.4k
            new = _set_subscript_context(p, expr, ctx);
337
23.4k
            break;
338
40.2k
        case Attribute_kind:
339
40.2k
            new = _set_attribute_context(p, expr, ctx);
340
40.2k
            break;
341
237
        case Starred_kind:
342
237
            new = _set_starred_context(p, expr, ctx);
343
237
            break;
344
0
        default:
345
0
            new = expr;
346
774k
    }
347
774k
    return new;
348
774k
}
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
1.03M
{
355
1.03M
    assert(expr != NULL);
356
1.03M
    assert(targets_type != FOR_TARGETS);
357
1.03M
    if (_PyPegen_get_invalid_target(expr, targets_type) != NULL) {
358
341k
        return NULL;
359
341k
    }
360
692k
    return _PyPegen_set_expr_context(
361
692k
        p, expr, targets_type == DEL_TARGETS ? Del : Store);
362
1.03M
}
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
1.46M
{
368
1.46M
    KeyValuePair *a = _PyArena_Malloc(p->arena, sizeof(KeyValuePair));
369
1.46M
    if (!a) {
370
0
        return NULL;
371
0
    }
372
1.46M
    a->key = key;
373
1.46M
    a->value = value;
374
1.46M
    return a;
375
1.46M
}
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
345k
{
381
345k
    Py_ssize_t len = asdl_seq_LEN(seq);
382
345k
    asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena);
383
345k
    if (!new_seq) {
384
0
        return NULL;
385
0
    }
386
1.47M
    for (Py_ssize_t i = 0; i < len; i++) {
387
1.13M
        KeyValuePair *pair = asdl_seq_GET_UNTYPED(seq, i);
388
1.13M
        asdl_seq_SET(new_seq, i, pair->key);
389
1.13M
    }
390
345k
    return new_seq;
391
345k
}
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
345k
{
397
345k
    Py_ssize_t len = asdl_seq_LEN(seq);
398
345k
    asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena);
399
345k
    if (!new_seq) {
400
0
        return NULL;
401
0
    }
402
1.47M
    for (Py_ssize_t i = 0; i < len; i++) {
403
1.13M
        KeyValuePair *pair = asdl_seq_GET_UNTYPED(seq, i);
404
1.13M
        asdl_seq_SET(new_seq, i, pair->value);
405
1.13M
    }
406
345k
    return new_seq;
407
345k
}
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
25.2k
{
413
25.2k
    KeyPatternPair *a = _PyArena_Malloc(p->arena, sizeof(KeyPatternPair));
414
25.2k
    if (!a) {
415
0
        return NULL;
416
0
    }
417
25.2k
    a->key = key;
418
25.2k
    a->pattern = pattern;
419
25.2k
    return a;
420
25.2k
}
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
412
{
426
412
    Py_ssize_t len = asdl_seq_LEN(seq);
427
412
    asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena);
428
412
    if (!new_seq) {
429
0
        return NULL;
430
0
    }
431
1.83k
    for (Py_ssize_t i = 0; i < len; i++) {
432
1.41k
        KeyPatternPair *pair = asdl_seq_GET_UNTYPED(seq, i);
433
1.41k
        asdl_seq_SET(new_seq, i, pair->key);
434
1.41k
    }
435
412
    return new_seq;
436
412
}
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
412
{
442
412
    Py_ssize_t len = asdl_seq_LEN(seq);
443
412
    asdl_pattern_seq *new_seq = _Py_asdl_pattern_seq_new(len, p->arena);
444
412
    if (!new_seq) {
445
0
        return NULL;
446
0
    }
447
1.83k
    for (Py_ssize_t i = 0; i < len; i++) {
448
1.41k
        KeyPatternPair *pair = asdl_seq_GET_UNTYPED(seq, i);
449
1.41k
        asdl_seq_SET(new_seq, i, pair->pattern);
450
1.41k
    }
451
412
    return new_seq;
452
412
}
453
454
/* Constructs a NameDefaultPair */
455
NameDefaultPair *
456
_PyPegen_name_default_pair(Parser *p, arg_ty arg, expr_ty value, Token *tc)
457
4.69M
{
458
4.69M
    NameDefaultPair *a = _PyArena_Malloc(p->arena, sizeof(NameDefaultPair));
459
4.69M
    if (!a) {
460
0
        return NULL;
461
0
    }
462
4.69M
    a->arg = _PyPegen_add_type_comment_to_arg(p, arg, tc);
463
4.69M
    if (!a->arg) {
464
5
        return NULL;
465
5
    }
466
4.69M
    a->value = value;
467
4.69M
    return a;
468
4.69M
}
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
7.96k
{
474
7.96k
    SlashWithDefault *a = _PyArena_Malloc(p->arena, sizeof(SlashWithDefault));
475
7.96k
    if (!a) {
476
0
        return NULL;
477
0
    }
478
7.96k
    a->plain_names = plain_names;
479
7.96k
    a->names_with_defaults = names_with_defaults;
480
7.96k
    return a;
481
7.96k
}
482
483
/* Constructs a StarEtc */
484
StarEtc *
485
_PyPegen_star_etc(Parser *p, arg_ty vararg, asdl_seq *kwonlyargs, arg_ty kwarg)
486
19.5k
{
487
19.5k
    StarEtc *a = _PyArena_Malloc(p->arena, sizeof(StarEtc));
488
19.5k
    if (!a) {
489
0
        return NULL;
490
0
    }
491
19.5k
    a->vararg = vararg;
492
19.5k
    a->kwonlyargs = kwonlyargs;
493
19.5k
    a->kwarg = kwarg;
494
19.5k
    return a;
495
19.5k
}
496
497
asdl_seq *
498
_PyPegen_join_sequences(Parser *p, asdl_seq *a, asdl_seq *b)
499
22.0k
{
500
22.0k
    Py_ssize_t first_len = asdl_seq_LEN(a);
501
22.0k
    Py_ssize_t second_len = asdl_seq_LEN(b);
502
22.0k
    asdl_seq *new_seq = (asdl_seq*)_Py_asdl_generic_seq_new(first_len + second_len, p->arena);
503
22.0k
    if (!new_seq) {
504
0
        return NULL;
505
0
    }
506
507
22.0k
    int k = 0;
508
3.10M
    for (Py_ssize_t i = 0; i < first_len; i++) {
509
3.08M
        asdl_seq_SET_UNTYPED(new_seq, k++, asdl_seq_GET_UNTYPED(a, i));
510
3.08M
    }
511
31.6k
    for (Py_ssize_t i = 0; i < second_len; i++) {
512
9.56k
        asdl_seq_SET_UNTYPED(new_seq, k++, asdl_seq_GET_UNTYPED(b, i));
513
9.56k
    }
514
515
22.0k
    return new_seq;
516
22.0k
}
517
518
static asdl_arg_seq*
519
_get_names(Parser *p, asdl_seq *names_with_defaults)
520
38.4k
{
521
38.4k
    Py_ssize_t len = asdl_seq_LEN(names_with_defaults);
522
38.4k
    asdl_arg_seq *seq = _Py_asdl_arg_seq_new(len, p->arena);
523
38.4k
    if (!seq) {
524
0
        return NULL;
525
0
    }
526
67.0k
    for (Py_ssize_t i = 0; i < len; i++) {
527
28.6k
        NameDefaultPair *pair = asdl_seq_GET_UNTYPED(names_with_defaults, i);
528
28.6k
        asdl_seq_SET(seq, i, pair->arg);
529
28.6k
    }
530
38.4k
    return seq;
531
38.4k
}
532
533
static asdl_expr_seq *
534
_get_defaults(Parser *p, asdl_seq *names_with_defaults)
535
38.4k
{
536
38.4k
    Py_ssize_t len = asdl_seq_LEN(names_with_defaults);
537
38.4k
    asdl_expr_seq *seq = _Py_asdl_expr_seq_new(len, p->arena);
538
38.4k
    if (!seq) {
539
0
        return NULL;
540
0
    }
541
67.0k
    for (Py_ssize_t i = 0; i < len; i++) {
542
28.6k
        NameDefaultPair *pair = asdl_seq_GET_UNTYPED(names_with_defaults, i);
543
28.6k
        asdl_seq_SET(seq, i, pair->value);
544
28.6k
    }
545
38.4k
    return seq;
546
38.4k
}
547
548
static int
549
_make_posonlyargs(Parser *p,
550
                  asdl_arg_seq *slash_without_default,
551
                  SlashWithDefault *slash_with_default,
552
37.9k
                  asdl_arg_seq **posonlyargs) {
553
37.9k
    if (slash_without_default != NULL) {
554
2.66k
        *posonlyargs = slash_without_default;
555
2.66k
    }
556
35.2k
    else if (slash_with_default != NULL) {
557
2.91k
        asdl_arg_seq *slash_with_default_names =
558
2.91k
                _get_names(p, slash_with_default->names_with_defaults);
559
2.91k
        if (!slash_with_default_names) {
560
0
            return -1;
561
0
        }
562
2.91k
        *posonlyargs = (asdl_arg_seq*)_PyPegen_join_sequences(
563
2.91k
                p,
564
2.91k
                (asdl_seq*)slash_with_default->plain_names,
565
2.91k
                (asdl_seq*)slash_with_default_names);
566
2.91k
    }
567
32.3k
    else {
568
32.3k
        *posonlyargs = _Py_asdl_arg_seq_new(0, p->arena);
569
32.3k
    }
570
37.9k
    return *posonlyargs == NULL ? -1 : 0;
571
37.9k
}
572
573
static int
574
_make_posargs(Parser *p,
575
              asdl_arg_seq *plain_names,
576
              asdl_seq *names_with_default,
577
37.9k
              asdl_arg_seq **posargs) {
578
579
37.9k
    if (names_with_default != NULL) {
580
20.3k
        if (plain_names != NULL) {
581
15.0k
            asdl_arg_seq *names_with_default_names = _get_names(p, names_with_default);
582
15.0k
            if (!names_with_default_names) {
583
0
                return -1;
584
0
            }
585
15.0k
            *posargs = (asdl_arg_seq*)_PyPegen_join_sequences(
586
15.0k
                    p,(asdl_seq*)plain_names, (asdl_seq*)names_with_default_names);
587
15.0k
        }
588
5.30k
        else {
589
5.30k
            *posargs = _get_names(p, names_with_default);
590
5.30k
        }
591
20.3k
    }
592
17.5k
    else {
593
17.5k
        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
17.5k
        else {
600
17.5k
            *posargs = _Py_asdl_arg_seq_new(0, p->arena);
601
17.5k
        }
602
17.5k
    }
603
37.9k
    return *posargs == NULL ? -1 : 0;
604
37.9k
}
605
606
static int
607
_make_posdefaults(Parser *p,
608
                  SlashWithDefault *slash_with_default,
609
                  asdl_seq *names_with_default,
610
37.9k
                  asdl_expr_seq **posdefaults) {
611
37.9k
    if (slash_with_default != NULL && names_with_default != NULL) {
612
2.91k
        asdl_expr_seq *slash_with_default_values =
613
2.91k
                _get_defaults(p, slash_with_default->names_with_defaults);
614
2.91k
        if (!slash_with_default_values) {
615
0
            return -1;
616
0
        }
617
2.91k
        asdl_expr_seq *names_with_default_values = _get_defaults(p, names_with_default);
618
2.91k
        if (!names_with_default_values) {
619
0
            return -1;
620
0
        }
621
2.91k
        *posdefaults = (asdl_expr_seq*)_PyPegen_join_sequences(
622
2.91k
                p,
623
2.91k
                (asdl_seq*)slash_with_default_values,
624
2.91k
                (asdl_seq*)names_with_default_values);
625
2.91k
    }
626
35.0k
    else if (slash_with_default == NULL && names_with_default != NULL) {
627
17.4k
        *posdefaults = _get_defaults(p, names_with_default);
628
17.4k
    }
629
17.5k
    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
17.5k
    else {
633
17.5k
        *posdefaults = _Py_asdl_expr_seq_new(0, p->arena);
634
17.5k
    }
635
37.9k
    return *posdefaults == NULL ? -1 : 0;
636
37.9k
}
637
638
static int
639
_make_kwargs(Parser *p, StarEtc *star_etc,
640
             asdl_arg_seq **kwonlyargs,
641
37.9k
             asdl_expr_seq **kwdefaults) {
642
37.9k
    if (star_etc != NULL && star_etc->kwonlyargs != NULL) {
643
15.1k
        *kwonlyargs = _get_names(p, star_etc->kwonlyargs);
644
15.1k
    }
645
22.8k
    else {
646
22.8k
        *kwonlyargs = _Py_asdl_arg_seq_new(0, p->arena);
647
22.8k
    }
648
649
37.9k
    if (*kwonlyargs == NULL) {
650
0
        return -1;
651
0
    }
652
653
37.9k
    if (star_etc != NULL && star_etc->kwonlyargs != NULL) {
654
15.1k
        *kwdefaults = _get_defaults(p, star_etc->kwonlyargs);
655
15.1k
    }
656
22.8k
    else {
657
22.8k
        *kwdefaults = _Py_asdl_expr_seq_new(0, p->arena);
658
22.8k
    }
659
660
37.9k
    if (*kwdefaults == NULL) {
661
0
        return -1;
662
0
    }
663
664
37.9k
    return 0;
665
37.9k
}
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
37.9k
{
673
37.9k
    asdl_arg_seq *posonlyargs;
674
37.9k
    if (_make_posonlyargs(p, slash_without_default, slash_with_default, &posonlyargs) == -1) {
675
0
        return NULL;
676
0
    }
677
678
37.9k
    asdl_arg_seq *posargs;
679
37.9k
    if (_make_posargs(p, plain_names, names_with_default, &posargs) == -1) {
680
0
        return NULL;
681
0
    }
682
683
37.9k
    asdl_expr_seq *posdefaults;
684
37.9k
    if (_make_posdefaults(p,slash_with_default, names_with_default, &posdefaults) == -1) {
685
0
        return NULL;
686
0
    }
687
688
37.9k
    arg_ty vararg = NULL;
689
37.9k
    if (star_etc != NULL && star_etc->vararg != NULL) {
690
14.4k
        vararg = star_etc->vararg;
691
14.4k
    }
692
693
37.9k
    asdl_arg_seq *kwonlyargs;
694
37.9k
    asdl_expr_seq *kwdefaults;
695
37.9k
    if (_make_kwargs(p, star_etc, &kwonlyargs, &kwdefaults) == -1) {
696
0
        return NULL;
697
0
    }
698
699
37.9k
    arg_ty kwarg = NULL;
700
37.9k
    if (star_etc != NULL && star_etc->kwarg != NULL) {
701
4.47k
        kwarg = star_etc->kwarg;
702
4.47k
    }
703
704
37.9k
    return _PyAST_arguments(posonlyargs, posargs, vararg, kwonlyargs,
705
37.9k
                            kwdefaults, kwarg, posdefaults, p->arena);
706
37.9k
}
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
8.77k
{
714
8.77k
    asdl_arg_seq *posonlyargs = _Py_asdl_arg_seq_new(0, p->arena);
715
8.77k
    if (!posonlyargs) {
716
0
        return NULL;
717
0
    }
718
8.77k
    asdl_arg_seq *posargs = _Py_asdl_arg_seq_new(0, p->arena);
719
8.77k
    if (!posargs) {
720
0
        return NULL;
721
0
    }
722
8.77k
    asdl_expr_seq *posdefaults = _Py_asdl_expr_seq_new(0, p->arena);
723
8.77k
    if (!posdefaults) {
724
0
        return NULL;
725
0
    }
726
8.77k
    asdl_arg_seq *kwonlyargs = _Py_asdl_arg_seq_new(0, p->arena);
727
8.77k
    if (!kwonlyargs) {
728
0
        return NULL;
729
0
    }
730
8.77k
    asdl_expr_seq *kwdefaults = _Py_asdl_expr_seq_new(0, p->arena);
731
8.77k
    if (!kwdefaults) {
732
0
        return NULL;
733
0
    }
734
735
8.77k
    return _PyAST_arguments(posonlyargs, posargs, NULL, kwonlyargs,
736
8.77k
                            kwdefaults, NULL, posdefaults, p->arena);
737
8.77k
}
738
739
/* Encapsulates the value of an operator_ty into an AugOperator struct */
740
AugOperator *
741
_PyPegen_augoperator(Parser *p, operator_ty kind)
742
12.9k
{
743
12.9k
    AugOperator *a = _PyArena_Malloc(p->arena, sizeof(AugOperator));
744
12.9k
    if (!a) {
745
0
        return NULL;
746
0
    }
747
12.9k
    a->kind = kind;
748
12.9k
    return a;
749
12.9k
}
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
1.53k
{
755
1.53k
    assert(function_def != NULL);
756
1.53k
    if (function_def->kind == AsyncFunctionDef_kind) {
757
310
        return _PyAST_AsyncFunctionDef(
758
310
            function_def->v.AsyncFunctionDef.name,
759
310
            function_def->v.AsyncFunctionDef.args,
760
310
            function_def->v.AsyncFunctionDef.body, decorators,
761
310
            function_def->v.AsyncFunctionDef.returns,
762
310
            function_def->v.AsyncFunctionDef.type_comment,
763
310
            function_def->v.AsyncFunctionDef.type_params,
764
310
            function_def->lineno, function_def->col_offset,
765
310
            function_def->end_lineno, function_def->end_col_offset, p->arena);
766
310
    }
767
768
1.22k
    return _PyAST_FunctionDef(
769
1.22k
        function_def->v.FunctionDef.name,
770
1.22k
        function_def->v.FunctionDef.args,
771
1.22k
        function_def->v.FunctionDef.body, decorators,
772
1.22k
        function_def->v.FunctionDef.returns,
773
1.22k
        function_def->v.FunctionDef.type_comment,
774
1.22k
        function_def->v.FunctionDef.type_params,
775
1.22k
        function_def->lineno, function_def->col_offset,
776
1.22k
        function_def->end_lineno, function_def->end_col_offset, p->arena);
777
1.53k
}
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
1.28k
{
783
1.28k
    assert(class_def != NULL);
784
1.28k
    return _PyAST_ClassDef(
785
1.28k
        class_def->v.ClassDef.name,
786
1.28k
        class_def->v.ClassDef.bases, class_def->v.ClassDef.keywords,
787
1.28k
        class_def->v.ClassDef.body, decorators,
788
1.28k
        class_def->v.ClassDef.type_params,
789
1.28k
        class_def->lineno, class_def->col_offset, class_def->end_lineno,
790
1.28k
        class_def->end_col_offset, p->arena);
791
1.28k
}
792
793
/* Construct a KeywordOrStarred */
794
KeywordOrStarred *
795
_PyPegen_keyword_or_starred(Parser *p, void *element, int is_keyword)
796
53.1k
{
797
53.1k
    KeywordOrStarred *a = _PyArena_Malloc(p->arena, sizeof(KeywordOrStarred));
798
53.1k
    if (!a) {
799
0
        return NULL;
800
0
    }
801
53.1k
    a->element = element;
802
53.1k
    a->is_keyword = is_keyword;
803
53.1k
    return a;
804
53.1k
}
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
42.0k
{
810
42.0k
    int n = 0;
811
129k
    for (Py_ssize_t i = 0, l = asdl_seq_LEN(seq); i < l; i++) {
812
87.2k
        KeywordOrStarred *k = asdl_seq_GET_UNTYPED(seq, i);
813
87.2k
        if (!k->is_keyword) {
814
6.51k
            n++;
815
6.51k
        }
816
87.2k
    }
817
42.0k
    return n;
818
42.0k
}
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
21.0k
{
824
21.0k
    int new_len = _seq_number_of_starred_exprs(kwargs);
825
21.0k
    if (new_len == 0) {
826
20.3k
        return NULL;
827
20.3k
    }
828
714
    asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(new_len, p->arena);
829
714
    if (!new_seq) {
830
0
        return NULL;
831
0
    }
832
833
714
    int idx = 0;
834
7.23k
    for (Py_ssize_t i = 0, len = asdl_seq_LEN(kwargs); i < len; i++) {
835
6.51k
        KeywordOrStarred *k = asdl_seq_GET_UNTYPED(kwargs, i);
836
6.51k
        if (!k->is_keyword) {
837
3.25k
            asdl_seq_SET(new_seq, idx++, k->element);
838
3.25k
        }
839
6.51k
    }
840
714
    return new_seq;
841
714
}
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
21.0k
{
847
21.0k
    Py_ssize_t len = asdl_seq_LEN(kwargs);
848
21.0k
    Py_ssize_t new_len = len - _seq_number_of_starred_exprs(kwargs);
849
21.0k
    if (new_len == 0) {
850
0
        return NULL;
851
0
    }
852
21.0k
    asdl_keyword_seq *new_seq = _Py_asdl_keyword_seq_new(new_len, p->arena);
853
21.0k
    if (!new_seq) {
854
0
        return NULL;
855
0
    }
856
857
21.0k
    int idx = 0;
858
64.6k
    for (Py_ssize_t i = 0; i < len; i++) {
859
43.6k
        KeywordOrStarred *k = asdl_seq_GET_UNTYPED(kwargs, i);
860
43.6k
        if (k->is_keyword) {
861
40.3k
            asdl_seq_SET(new_seq, idx++, k->element);
862
40.3k
        }
863
43.6k
    }
864
21.0k
    return new_seq;
865
21.0k
}
866
867
expr_ty
868
_PyPegen_ensure_imaginary(Parser *p, expr_ty exp)
869
8.54k
{
870
8.54k
    if (exp->kind != Constant_kind || !PyComplex_CheckExact(exp->v.Constant.value)) {
871
6
        RAISE_SYNTAX_ERROR_KNOWN_LOCATION(exp, "imaginary number required in complex literal");
872
6
        return NULL;
873
6
    }
874
8.54k
    return exp;
875
8.54k
}
876
877
expr_ty
878
_PyPegen_ensure_real(Parser *p, expr_ty exp)
879
12.5k
{
880
12.5k
    if (exp->kind != Constant_kind || PyComplex_CheckExact(exp->v.Constant.value)) {
881
6
        RAISE_SYNTAX_ERROR_KNOWN_LOCATION(exp, "real number required in complex literal");
882
6
        return NULL;
883
6
    }
884
12.5k
    return exp;
885
12.5k
}
886
887
mod_ty
888
12.3k
_PyPegen_make_module(Parser *p, asdl_stmt_seq *a) {
889
12.3k
    asdl_type_ignore_seq *type_ignores = NULL;
890
12.3k
    Py_ssize_t num = p->type_ignore_comments.num_items;
891
12.3k
    if (num > 0) {
892
        // Turn the raw (comment, lineno) pairs into TypeIgnore objects in the arena
893
41
        type_ignores = _Py_asdl_type_ignore_seq_new(num, p->arena);
894
41
        if (type_ignores == NULL) {
895
0
            return NULL;
896
0
        }
897
962
        for (Py_ssize_t i = 0; i < num; i++) {
898
925
            PyObject *tag = _PyPegen_new_type_comment(p, p->type_ignore_comments.items[i].comment);
899
925
            if (tag == NULL) {
900
4
                return NULL;
901
4
            }
902
921
            type_ignore_ty ti = _PyAST_TypeIgnore(p->type_ignore_comments.items[i].lineno,
903
921
                                                  tag, p->arena);
904
921
            if (ti == NULL) {
905
0
                return NULL;
906
0
            }
907
921
            asdl_seq_SET(type_ignores, i, ti);
908
921
        }
909
41
    }
910
12.3k
    return _PyAST_Module(a, type_ignores, p->arena);
911
12.3k
}
912
913
PyObject *
914
_PyPegen_new_type_comment(Parser *p, const char *s)
915
1.81k
{
916
1.81k
    PyObject *res = PyUnicode_DecodeUTF8(s, strlen(s), NULL);
917
1.81k
    if (res == NULL) {
918
17
        return NULL;
919
17
    }
920
1.80k
    if (_PyArena_AddPyObject(p->arena, res) < 0) {
921
0
        Py_DECREF(res);
922
0
        return NULL;
923
0
    }
924
1.80k
    return res;
925
1.80k
}
926
927
arg_ty
928
_PyPegen_add_type_comment_to_arg(Parser *p, arg_ty a, Token *tc)
929
4.78M
{
930
4.78M
    if (tc == NULL) {
931
4.78M
        return a;
932
4.78M
    }
933
210
    const char *bytes = PyBytes_AsString(tc->bytes);
934
210
    if (bytes == NULL) {
935
0
        return NULL;
936
0
    }
937
210
    PyObject *tco = _PyPegen_new_type_comment(p, bytes);
938
210
    if (tco == NULL) {
939
8
        return NULL;
940
8
    }
941
202
    return _PyAST_arg(a->arg, a->annotation, tco,
942
202
                      a->lineno, a->col_offset, a->end_lineno, a->end_col_offset,
943
202
                      p->arena);
944
210
}
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.62k
_PyPegen_check_barry_as_flufl(Parser *p, Token* t) {
950
1.62k
    assert(t->bytes != NULL);
951
1.62k
    assert(t->type == NOTEQUAL);
952
953
1.62k
    const char* tok_str = PyBytes_AS_STRING(t->bytes);
954
1.62k
    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.62k
    if (!(p->flags & PyPARSE_BARRY_AS_BDFL)) {
959
1.62k
        return strcmp(tok_str, "!=");
960
1.62k
    }
961
0
    return 0;
962
1.62k
}
963
964
int
965
31.1k
_PyPegen_check_legacy_stmt(Parser *p, expr_ty name) {
966
31.1k
    if (name->kind != Name_kind) {
967
4.22k
        return 0;
968
4.22k
    }
969
26.9k
    const char* candidates[2] = {"print", "exec"};
970
77.4k
    for (int i=0; i<2; i++) {
971
53.9k
        if (PyUnicode_CompareWithASCIIString(name->v.Name.id, candidates[i]) == 0) {
972
3.40k
            return 1;
973
3.40k
        }
974
53.9k
    }
975
23.5k
    return 0;
976
26.9k
}
977
978
void *
979
_PyPegen_raise_error_for_missing_comma(Parser *p, expr_ty a, expr_ty b)
980
18.8k
{
981
    // Don't raise for legacy statements like "print x" or "exec x"
982
18.8k
    if (_PyPegen_check_legacy_stmt(p, a)) {
983
3.39k
        return NULL;
984
3.39k
    }
985
    // Only raise inside parentheses/brackets (level > 0)
986
15.4k
    if (p->tokens[p->mark - 1]->level == 0) {
987
15.1k
        return NULL;
988
15.1k
    }
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
324
    if (a->end_lineno > a->lineno) {
994
12
        return RAISE_ERROR_KNOWN_LOCATION(
995
12
            p, PyExc_SyntaxError, a->end_lineno, a->col_offset,
996
12
            a->end_lineno, a->end_col_offset,
997
12
            "invalid syntax. Perhaps you forgot a comma?"
998
12
        );
999
12
    }
1000
312
    return RAISE_ERROR_KNOWN_LOCATION(
1001
312
        p, PyExc_SyntaxError, a->lineno, a->col_offset,
1002
312
        b->end_lineno, b->end_col_offset,
1003
312
        "invalid syntax. Perhaps you forgot a comma?"
1004
312
    );
1005
324
}
1006
1007
static ResultTokenWithMetadata *
1008
result_token_with_metadata(Parser *p, void *result, PyObject *metadata)
1009
27.9k
{
1010
27.9k
    ResultTokenWithMetadata *res = _PyArena_Malloc(p->arena, sizeof(ResultTokenWithMetadata));
1011
27.9k
    if (res == NULL) {
1012
0
        return NULL;
1013
0
    }
1014
27.9k
    res->metadata = metadata;
1015
27.9k
    res->result = result;
1016
27.9k
    return res;
1017
27.9k
}
1018
1019
static char
1020
formatted_string_prefix(const Parser *p)
1021
91
{
1022
91
    int nested = 0;
1023
3.24k
    for (int i = p->mark - 1; i >= 0; i--) {
1024
3.24k
        int type = p->tokens[i]->type;
1025
3.24k
        if (type == FSTRING_END || type == TSTRING_END) {
1026
165
            nested++;
1027
165
        }
1028
3.07k
        else if (type == FSTRING_START || type == TSTRING_START) {
1029
256
            if (nested == 0) {
1030
91
                return type == TSTRING_START ? 't' : 'f';
1031
91
            }
1032
165
            nested--;
1033
165
        }
1034
3.24k
    }
1035
91
    Py_UNREACHABLE();
1036
91
}
1037
1038
ResultTokenWithMetadata *
1039
_PyPegen_check_fstring_conversion(Parser *p, Token* conv_token, expr_ty conv)
1040
6.92k
{
1041
6.92k
    if (conv_token->lineno != conv->lineno || conv_token->end_col_offset != conv->col_offset) {
1042
17
        return RAISE_SYNTAX_ERROR_KNOWN_RANGE(
1043
17
            conv_token, conv,
1044
17
            "%c-string: conversion type must come right after the exclamation mark",
1045
17
            formatted_string_prefix(p)
1046
17
        );
1047
17
    }
1048
1049
6.90k
    Py_UCS4 first = PyUnicode_READ_CHAR(conv->v.Name.id, 0);
1050
6.90k
    if (PyUnicode_GET_LENGTH(conv->v.Name.id) > 1 ||
1051
6.85k
            !(first == 's' || first == 'r' || first == 'a')) {
1052
74
        RAISE_SYNTAX_ERROR_KNOWN_LOCATION(conv,
1053
74
                                            "%c-string: invalid conversion character %R: expected 's', 'r', or 'a'",
1054
74
                                            formatted_string_prefix(p),
1055
74
                                            conv->v.Name.id);
1056
74
        return NULL;
1057
74
    }
1058
1059
6.83k
    return result_token_with_metadata(p, conv, conv_token->metadata);
1060
6.90k
}
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
21.1k
{
1066
21.1k
    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
21.1k
    Py_ssize_t n_items = asdl_seq_LEN(spec);
1074
21.1k
    Py_ssize_t non_empty_count = 0;
1075
61.5k
    for (Py_ssize_t i = 0; i < n_items; i++) {
1076
40.4k
        expr_ty item = asdl_seq_GET(spec, i);
1077
40.4k
        non_empty_count += !(item->kind == Constant_kind &&
1078
40.4k
                             PyUnicode_CheckExact(item->v.Constant.value) &&
1079
27.6k
                             PyUnicode_GET_LENGTH(item->v.Constant.value) == 0);
1080
40.4k
    }
1081
21.1k
    if (non_empty_count != n_items) {
1082
9.82k
        asdl_expr_seq *resized_spec =
1083
9.82k
            _Py_asdl_expr_seq_new(non_empty_count, p->arena);
1084
9.82k
        if (resized_spec == NULL) {
1085
0
            return NULL;
1086
0
        }
1087
9.82k
        Py_ssize_t j = 0;
1088
30.9k
        for (Py_ssize_t i = 0; i < n_items; i++) {
1089
21.0k
            expr_ty item = asdl_seq_GET(spec, i);
1090
21.0k
            if (item->kind == Constant_kind &&
1091
21.0k
                PyUnicode_CheckExact(item->v.Constant.value) &&
1092
13.5k
                PyUnicode_GET_LENGTH(item->v.Constant.value) == 0) {
1093
9.82k
                continue;
1094
9.82k
            }
1095
11.2k
            asdl_seq_SET(resized_spec, j++, item);
1096
11.2k
        }
1097
9.82k
        assert(j == non_empty_count);
1098
9.82k
        spec = resized_spec;
1099
9.82k
    }
1100
21.1k
    expr_ty res;
1101
21.1k
    Py_ssize_t n = asdl_seq_LEN(spec);
1102
21.1k
    if (n == 0 || (n == 1 && asdl_seq_GET(spec, 0)->kind == Constant_kind)) {
1103
12.3k
        res = _PyAST_JoinedStr(spec, lineno, col_offset, end_lineno,
1104
12.3k
                                    end_col_offset, p->arena);
1105
12.3k
    } else {
1106
8.82k
        res = _PyPegen_concatenate_strings(p, spec,
1107
8.82k
                             lineno, col_offset, end_lineno,
1108
8.82k
                             end_col_offset, arena);
1109
8.82k
    }
1110
21.1k
    if (!res) {
1111
0
        return NULL;
1112
0
    }
1113
21.1k
    return result_token_with_metadata(p, res, colon->metadata);
1114
21.1k
}
1115
1116
const char *
1117
_PyPegen_get_expr_name(expr_ty e)
1118
230
{
1119
230
    assert(e != NULL);
1120
230
    switch (e->kind) {
1121
1
        case Attribute_kind:
1122
1
            return "attribute";
1123
1
        case Subscript_kind:
1124
1
            return "subscript";
1125
6
        case Starred_kind:
1126
6
            return "starred";
1127
6
        case Name_kind:
1128
6
            return "name";
1129
2
        case List_kind:
1130
2
            return "list";
1131
11
        case Tuple_kind:
1132
11
            return "tuple";
1133
7
        case Lambda_kind:
1134
7
            return "lambda";
1135
11
        case Call_kind:
1136
11
            return "function call";
1137
4
        case BoolOp_kind:
1138
57
        case BinOp_kind:
1139
71
        case UnaryOp_kind:
1140
71
            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
2
        case SetComp_kind:
1151
2
            return "set comprehension";
1152
2
        case DictComp_kind:
1153
2
            return "dict comprehension";
1154
3
        case Dict_kind:
1155
3
            return "dict literal";
1156
1
        case Set_kind:
1157
1
            return "set display";
1158
4
        case JoinedStr_kind:
1159
4
        case FormattedValue_kind:
1160
4
            return "f-string expression";
1161
2
        case TemplateStr_kind:
1162
2
        case Interpolation_kind:
1163
2
            return "t-string expression";
1164
77
        case Constant_kind: {
1165
77
            PyObject *value = e->v.Constant.value;
1166
77
            if (value == Py_None) {
1167
1
                return "None";
1168
1
            }
1169
76
            if (value == Py_False) {
1170
2
                return "False";
1171
2
            }
1172
74
            if (value == Py_True) {
1173
3
                return "True";
1174
3
            }
1175
71
            if (value == Py_Ellipsis) {
1176
1
                return "ellipsis";
1177
1
            }
1178
70
            return "literal";
1179
71
        }
1180
17
        case Compare_kind:
1181
17
            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
230
    }
1192
230
}
1193
1194
expr_ty
1195
20
_PyPegen_get_last_comprehension_item(comprehension_ty comprehension) {
1196
20
    if (comprehension->ifs == NULL || asdl_seq_LEN(comprehension->ifs) == 0) {
1197
14
        return comprehension->iter;
1198
14
    }
1199
6
    return PyPegen_last_item(comprehension->ifs, expr_ty);
1200
20
}
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
64.8k
                     int end_col_offset, PyArena *arena) {
1205
64.8k
    Py_ssize_t args_len = asdl_seq_LEN(a);
1206
64.8k
    Py_ssize_t total_len = args_len;
1207
1208
64.8k
    if (b == NULL) {
1209
60.6k
        return _PyAST_Call(_PyPegen_dummy_name(p), a, NULL, lineno, col_offset,
1210
60.6k
                        end_lineno, end_col_offset, arena);
1211
1212
60.6k
    }
1213
1214
4.26k
    asdl_expr_seq *starreds = _PyPegen_seq_extract_starred_exprs(p, b);
1215
4.26k
    if (!starreds && PyErr_Occurred()) {
1216
0
        return NULL;
1217
0
    }
1218
1219
4.26k
    asdl_keyword_seq *keywords = _PyPegen_seq_delete_starred_exprs(p, b);
1220
4.26k
    if (!keywords && PyErr_Occurred()) {
1221
0
        return NULL;
1222
0
    }
1223
1224
4.26k
    if (starreds) {
1225
349
        total_len += asdl_seq_LEN(starreds);
1226
349
    }
1227
1228
4.26k
    asdl_expr_seq *args = _Py_asdl_expr_seq_new(total_len, arena);
1229
4.26k
    if (args == NULL) {
1230
0
        return NULL;
1231
0
    }
1232
1233
4.26k
    Py_ssize_t i = 0;
1234
10.2k
    for (i = 0; i < args_len; i++) {
1235
5.97k
        asdl_seq_SET(args, i, asdl_seq_GET(a, i));
1236
5.97k
    }
1237
6.46k
    for (; i < total_len; i++) {
1238
2.20k
        asdl_seq_SET(args, i, asdl_seq_GET(starreds, i - args_len));
1239
2.20k
    }
1240
1241
4.26k
    return _PyAST_Call(_PyPegen_dummy_name(p), args, keywords, lineno,
1242
4.26k
                       col_offset, end_lineno, end_col_offset, arena);
1243
4.26k
}
1244
1245
// AST Error reporting helpers
1246
1247
expr_ty
1248
_PyPegen_get_invalid_target(expr_ty e, TARGETS_TYPE targets_type)
1249
1.04M
{
1250
1.04M
    if (e == NULL) {
1251
0
        return NULL;
1252
0
    }
1253
1254
1.04M
    if (targets_type == SINGLE_TARGETS ||
1255
784k
        targets_type == ATTRIBUTE_OR_SUBSCRIPT_TARGETS) {
1256
528k
        if (targets_type == SINGLE_TARGETS && e->kind == Name_kind) {
1257
195k
            return NULL;
1258
195k
        }
1259
333k
        return e->kind == Attribute_kind || e->kind == Subscript_kind ? NULL : e;
1260
528k
    }
1261
1262
515k
#define VISIT_CONTAINER(CONTAINER, TYPE) do { \
1263
10.7k
        Py_ssize_t len = asdl_seq_LEN((CONTAINER)->v.TYPE.elts);\
1264
17.1k
        for (Py_ssize_t i = 0; i < len; i++) {\
1265
7.09k
            expr_ty other = asdl_seq_GET((CONTAINER)->v.TYPE.elts, i);\
1266
7.09k
            expr_ty child = _PyPegen_get_invalid_target(other, targets_type);\
1267
7.09k
            if (child != NULL) {\
1268
726
                return child;\
1269
726
            }\
1270
7.09k
        }\
1271
10.7k
    } 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
515k
    switch (e->kind) {
1280
3.32k
        case List_kind:
1281
3.32k
            VISIT_CONTAINER(e, List);
1282
2.95k
            return NULL;
1283
7.43k
        case Tuple_kind:
1284
7.43k
            VISIT_CONTAINER(e, Tuple);
1285
7.09k
            return NULL;
1286
1.20k
        case Starred_kind:
1287
1.20k
            if (targets_type == DEL_TARGETS) {
1288
12
                return e;
1289
12
            }
1290
1.19k
            return _PyPegen_get_invalid_target(e->v.Starred.value, targets_type);
1291
209
        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
209
            if (targets_type == FOR_TARGETS) {
1296
101
                cmpop_ty cmpop = (cmpop_ty) asdl_seq_GET(e->v.Compare.ops, 0);
1297
101
                if (cmpop == In) {
1298
55
                    return _PyPegen_get_invalid_target(e->v.Compare.left, targets_type);
1299
55
                }
1300
46
                return NULL;
1301
101
            }
1302
108
            return e;
1303
430k
        case Name_kind:
1304
440k
        case Subscript_kind:
1305
457k
        case Attribute_kind:
1306
457k
            return NULL;
1307
45.7k
        default:
1308
45.7k
            return e;
1309
515k
    }
1310
515k
}
1311
1312
44
void *_PyPegen_arguments_parsing_error(Parser *p, expr_ty e) {
1313
44
    int kwarg_unpacking = 0;
1314
586
    for (Py_ssize_t i = 0, l = asdl_seq_LEN(e->v.Call.keywords); i < l; i++) {
1315
542
        keyword_ty keyword = asdl_seq_GET(e->v.Call.keywords, i);
1316
542
        if (!keyword->arg) {
1317
234
            kwarg_unpacking = 1;
1318
234
        }
1319
542
    }
1320
1321
44
    const char *msg = NULL;
1322
44
    if (kwarg_unpacking) {
1323
22
        msg = "positional argument follows keyword argument unpacking";
1324
22
    } else {
1325
22
        msg = "positional argument follows keyword argument";
1326
22
    }
1327
1328
44
    return RAISE_SYNTAX_ERROR(msg);
1329
44
}
1330
1331
void *
1332
_PyPegen_nonparen_genexp_in_call(Parser *p, expr_ty args, asdl_comprehension_seq *comprehensions)
1333
627
{
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
627
    Py_ssize_t len = asdl_seq_LEN(args->v.Call.args);
1342
627
    if (len <= 1) {
1343
625
        return NULL;
1344
625
    }
1345
1346
2
    comprehension_ty last_comprehension = PyPegen_last_item(comprehensions, comprehension_ty);
1347
1348
2
    return RAISE_SYNTAX_ERROR_KNOWN_RANGE(
1349
627
        (expr_ty) asdl_seq_GET(args->v.Call.args, len - 1),
1350
627
        _PyPegen_get_last_comprehension_item(last_comprehension),
1351
627
        "Generator expression must be parenthesized"
1352
627
    );
1353
627
}
1354
1355
// Fstring stuff
1356
1357
static expr_ty
1358
171k
_PyPegen_decode_fstring_part(Parser* p, int is_raw, expr_ty constant, Token* token) {
1359
171k
    assert(PyUnicode_CheckExact(constant->v.Constant.value));
1360
1361
171k
    const char* bstr = PyUnicode_AsUTF8(constant->v.Constant.value);
1362
171k
    if (bstr == NULL) {
1363
0
        return NULL;
1364
0
    }
1365
1366
171k
    size_t len;
1367
171k
    if (strcmp(bstr, "{{") == 0 || strcmp(bstr, "}}") == 0) {
1368
0
        len = 1;
1369
171k
    } else {
1370
171k
        len = strlen(bstr);
1371
171k
    }
1372
1373
171k
    is_raw = is_raw || strchr(bstr, '\\') == NULL;
1374
171k
    PyObject *str = _PyPegen_decode_string(p, is_raw, bstr, len, token);
1375
171k
    if (str == NULL) {
1376
14
        _Pypegen_raise_decode_error(p);
1377
14
        return NULL;
1378
14
    }
1379
171k
    if (_PyArena_AddPyObject(p->arena, str) < 0) {
1380
0
        Py_DECREF(str);
1381
0
        return NULL;
1382
0
    }
1383
171k
    return _PyAST_Constant(str, NULL, constant->lineno, constant->col_offset,
1384
171k
                           constant->end_lineno, constant->end_col_offset,
1385
171k
                           p->arena);
1386
171k
}
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
31.3k
{
1392
31.3k
    Py_ssize_t n_items = asdl_seq_LEN(raw_expressions);
1393
31.3k
    Py_ssize_t total_items = n_items;
1394
237k
    for (Py_ssize_t i = 0; i < n_items; i++) {
1395
206k
        expr_ty item = asdl_seq_GET(raw_expressions, i);
1396
206k
        if (item->kind == JoinedStr_kind) {
1397
2.28k
            total_items += asdl_seq_LEN(item->v.JoinedStr.values) - 1;
1398
2.28k
        }
1399
206k
    }
1400
1401
31.3k
    const char* quote_str = PyBytes_AsString(a->bytes);
1402
31.3k
    if (quote_str == NULL) {
1403
0
        return NULL;
1404
0
    }
1405
31.3k
    int is_raw = strpbrk(quote_str, "rR") != NULL;
1406
1407
31.3k
    asdl_expr_seq *seq = _Py_asdl_expr_seq_new(total_items, p->arena);
1408
31.3k
    if (seq == NULL) {
1409
0
        return NULL;
1410
0
    }
1411
1412
31.3k
    Py_ssize_t index = 0;
1413
221k
    for (Py_ssize_t i = 0; i < n_items; i++) {
1414
190k
        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
190k
        if (item->kind == JoinedStr_kind) {
1419
2.28k
            asdl_expr_seq *values = item->v.JoinedStr.values;
1420
2.28k
            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
2.28k
            expr_ty first = asdl_seq_GET(values, 0);
1430
2.28k
            assert(first->kind == Constant_kind);
1431
2.28k
            asdl_seq_SET(seq, index++, first);
1432
1433
2.28k
            expr_ty second = asdl_seq_GET(values, 1);
1434
2.28k
            assert((is_tstring &&
1435
2.28k
                    second->kind == Interpolation_kind) ||
1436
2.28k
                   second->kind == FormattedValue_kind);
1437
2.28k
            asdl_seq_SET(seq, index++, second);
1438
1439
2.28k
            continue;
1440
2.28k
        }
1441
1442
187k
        if (item->kind == Constant_kind) {
1443
171k
            item = _PyPegen_decode_fstring_part(p, is_raw, item, b);
1444
171k
            if (item == NULL) {
1445
14
                return NULL;
1446
14
            }
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
171k
            if (PyUnicode_CheckExact(item->v.Constant.value)
1452
171k
                && PyUnicode_GET_LENGTH(item->v.Constant.value) == 0) {
1453
2.41k
                continue;
1454
2.41k
            }
1455
171k
        }
1456
185k
        asdl_seq_SET(seq, index++, item);
1457
185k
    }
1458
1459
31.3k
    asdl_expr_seq *resized_exprs;
1460
31.3k
    if (index != total_items) {
1461
2.32k
        resized_exprs = _Py_asdl_expr_seq_new(index, p->arena);
1462
2.32k
        if (resized_exprs == NULL) {
1463
0
            return NULL;
1464
0
        }
1465
3.11k
        for (Py_ssize_t i = 0; i < index; i++) {
1466
790
            asdl_seq_SET(resized_exprs, i, asdl_seq_GET(seq, i));
1467
790
        }
1468
2.32k
    }
1469
28.9k
    else {
1470
28.9k
        resized_exprs = seq;
1471
28.9k
    }
1472
31.3k
    return resized_exprs;
1473
31.3k
}
1474
1475
expr_ty
1476
5.29k
_PyPegen_template_str(Parser *p, Token *a, asdl_expr_seq *raw_expressions, Token *b) {
1477
1478
5.29k
    asdl_expr_seq *resized_exprs = _get_resized_exprs(p, a, raw_expressions, b, 1);
1479
5.29k
    if (resized_exprs == NULL) {
1480
5
        return NULL;
1481
5
    }
1482
5.29k
    return _PyAST_TemplateStr(resized_exprs, a->lineno, a->col_offset,
1483
5.29k
                              b->end_lineno, b->end_col_offset,
1484
5.29k
                              p->arena);
1485
5.29k
}
1486
1487
expr_ty
1488
26.0k
_PyPegen_joined_str(Parser *p, Token* a, asdl_expr_seq* raw_expressions, Token*b) {
1489
1490
26.0k
    asdl_expr_seq *resized_exprs = _get_resized_exprs(p, a, raw_expressions, b, 0);
1491
26.0k
    if (resized_exprs == NULL) {
1492
9
        return NULL;
1493
9
    }
1494
26.0k
    return _PyAST_JoinedStr(resized_exprs, a->lineno, a->col_offset,
1495
26.0k
                            b->end_lineno, b->end_col_offset,
1496
26.0k
                            p->arena);
1497
26.0k
}
1498
1499
27.7k
expr_ty _PyPegen_decoded_constant_from_token(Parser* p, Token* tok) {
1500
27.7k
    Py_ssize_t bsize;
1501
27.7k
    char* bstr;
1502
27.7k
    if (PyBytes_AsStringAndSize(tok->bytes, &bstr, &bsize) == -1) {
1503
0
        return NULL;
1504
0
    }
1505
1506
27.7k
    int is_raw = tok->is_raw;
1507
1508
27.7k
    PyObject* str = _PyPegen_decode_string(p, is_raw, bstr, bsize, tok);
1509
27.7k
    if (str == NULL) {
1510
3
        return NULL;
1511
3
    }
1512
27.7k
    if (_PyArena_AddPyObject(p->arena, str) < 0) {
1513
0
        Py_DECREF(str);
1514
0
        return NULL;
1515
0
    }
1516
27.7k
    return _PyAST_Constant(str, NULL, tok->lineno, tok->col_offset,
1517
27.7k
                           tok->end_lineno, tok->end_col_offset,
1518
27.7k
                           p->arena);
1519
27.7k
}
1520
1521
198k
expr_ty _PyPegen_constant_from_token(Parser* p, Token* tok) {
1522
198k
    const char* bstr = PyBytes_AsString(tok->bytes);
1523
198k
    if (bstr == NULL) {
1524
0
        return NULL;
1525
0
    }
1526
198k
    PyObject* str = PyUnicode_FromString(bstr);
1527
198k
    if (str == NULL) {
1528
6
        return NULL;
1529
6
    }
1530
198k
    if (_PyArena_AddPyObject(p->arena, str) < 0) {
1531
0
        Py_DECREF(str);
1532
0
        return NULL;
1533
0
    }
1534
198k
    return _PyAST_Constant(str, NULL, tok->lineno, tok->col_offset,
1535
198k
                           tok->end_lineno, tok->end_col_offset,
1536
198k
                           p->arena);
1537
198k
}
1538
1539
103k
expr_ty _PyPegen_constant_from_string(Parser* p, Token* tok) {
1540
103k
    const char* the_str = PyBytes_AsString(tok->bytes);
1541
103k
    if (the_str == NULL) {
1542
0
        return NULL;
1543
0
    }
1544
103k
    PyObject *s = _PyPegen_parse_string(p, tok);
1545
103k
    if (s == NULL) {
1546
227
        _Pypegen_raise_decode_error(p);
1547
227
        return NULL;
1548
227
    }
1549
103k
    if (_PyArena_AddPyObject(p->arena, s) < 0) {
1550
0
        Py_DECREF(s);
1551
0
        return NULL;
1552
0
    }
1553
103k
    PyObject *kind = NULL;
1554
103k
    if (the_str && the_str[0] == 'u') {
1555
6.88k
        kind = _PyPegen_new_identifier(p, "u");
1556
6.88k
        if (kind == NULL) {
1557
0
            return NULL;
1558
0
        }
1559
6.88k
    }
1560
103k
    return _PyAST_Constant(s, kind, tok->lineno, tok->col_offset, tok->end_lineno, tok->end_col_offset, p->arena);
1561
103k
}
1562
1563
static int
1564
_get_interpolation_conversion(Parser *p, Token *debug, ResultTokenWithMetadata *conversion,
1565
                              ResultTokenWithMetadata *format)
1566
39.6k
{
1567
39.6k
    if (conversion != NULL) {
1568
6.79k
        expr_ty conversion_expr = (expr_ty) conversion->result;
1569
6.79k
        assert(conversion_expr->kind == Name_kind);
1570
6.79k
        Py_UCS4 first = PyUnicode_READ_CHAR(conversion_expr->v.Name.id, 0);
1571
6.79k
        return Py_SAFE_DOWNCAST(first, Py_UCS4, int);
1572
6.79k
    }
1573
32.8k
    else if (debug && !format) {
1574
        /* If no conversion is specified, use !r for debug expressions */
1575
3.64k
        return (int)'r';
1576
3.64k
    }
1577
29.2k
    return -1;
1578
39.6k
}
1579
1580
static PyObject *
1581
_strip_interpolation_debug_expr(PyObject *exprstr)
1582
2.98k
{
1583
2.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.99k
    while (len > 0) {
1588
2.99k
        int has_newline = 0;
1589
4.73k
        while (len > 0) {
1590
4.73k
            Py_UCS4 c = PyUnicode_READ_CHAR(exprstr, len - 1);
1591
4.73k
            if (!_PyUnicode_IsWhitespace(c)) {
1592
2.99k
                break;
1593
2.99k
            }
1594
1.74k
            if (c == '\r' || c == '\n') {
1595
292
                has_newline = 1;
1596
292
            }
1597
1.74k
            len--;
1598
1.74k
        }
1599
2.99k
        if (!has_newline || len == 0 ||
1600
214
            PyUnicode_READ_CHAR(exprstr, len - 1) != '\\')
1601
2.98k
        {
1602
2.98k
            break;
1603
2.98k
        }
1604
3
        len--;
1605
3
    }
1606
1607
    /* Preserve unexpected metadata instead of dropping source text. */
1608
2.98k
    if (len == 0 || PyUnicode_READ_CHAR(exprstr, len - 1) != '=') {
1609
0
        return Py_NewRef(exprstr);
1610
0
    }
1611
1612
2.98k
    return PyUnicode_Substring(exprstr, 0, len - 1);
1613
2.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
13.1k
                                 int end_lineno, int end_col_offset, PyArena *arena) {
1618
1619
13.1k
    int conversion_val = _get_interpolation_conversion(p, debug, conversion, format);
1620
1621
    /* Find the non whitespace token after the "=" */
1622
13.1k
    int debug_end_line, debug_end_offset;
1623
13.1k
    PyObject *debug_metadata;
1624
13.1k
    constant exprstr;
1625
1626
13.1k
    if (conversion) {
1627
1.90k
        debug_end_line = ((expr_ty) conversion->result)->lineno;
1628
1.90k
        debug_end_offset = ((expr_ty) conversion->result)->col_offset;
1629
1.90k
        debug_metadata = exprstr = conversion->metadata;
1630
1.90k
    }
1631
11.2k
    else if (format) {
1632
4.37k
        debug_end_line = ((expr_ty) format->result)->lineno;
1633
4.37k
        debug_end_offset = ((expr_ty) format->result)->col_offset + 1;
1634
4.37k
        debug_metadata = exprstr = format->metadata;
1635
4.37k
    }
1636
6.82k
    else {
1637
6.82k
        debug_end_line = end_lineno;
1638
6.82k
        debug_end_offset = end_col_offset;
1639
6.82k
        debug_metadata = exprstr = closing_brace->metadata;
1640
6.82k
    }
1641
1642
13.1k
    assert(exprstr != NULL);
1643
13.1k
    PyObject *final_exprstr = debug
1644
13.1k
        ? _strip_interpolation_debug_expr(exprstr)
1645
13.1k
        : Py_NewRef(exprstr);
1646
13.1k
    if (!final_exprstr || _PyArena_AddPyObject(arena, final_exprstr) < 0) {
1647
0
        Py_XDECREF(final_exprstr);
1648
0
        return NULL;
1649
0
    }
1650
1651
13.1k
    expr_ty interpolation = _PyAST_Interpolation(
1652
13.1k
        expression, final_exprstr, conversion_val, format ? (expr_ty) format->result : NULL,
1653
13.1k
        lineno, col_offset, end_lineno,
1654
13.1k
        end_col_offset, arena
1655
13.1k
    );
1656
1657
13.1k
    if (!interpolation || !debug) {
1658
10.1k
        return interpolation;
1659
10.1k
    }
1660
1661
2.98k
    expr_ty debug_text = _PyAST_Constant(debug_metadata, NULL, lineno, col_offset + 1, debug_end_line,
1662
2.98k
                                            debug_end_offset - 1, p->arena);
1663
2.98k
    if (!debug_text) {
1664
0
        return NULL;
1665
0
    }
1666
1667
2.98k
    asdl_expr_seq *values = _Py_asdl_expr_seq_new(2, arena);
1668
2.98k
    if (!values) {
1669
0
        return NULL;
1670
0
    }
1671
2.98k
    asdl_seq_SET(values, 0, debug_text);
1672
2.98k
    asdl_seq_SET(values, 1, interpolation);
1673
2.98k
    return _PyAST_JoinedStr(values, lineno, col_offset, debug_end_line, debug_end_offset, p->arena);
1674
2.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
26.5k
                                 int end_lineno, int end_col_offset, PyArena *arena) {
1679
26.5k
    int conversion_val = _get_interpolation_conversion(p, debug, conversion, format);
1680
1681
26.5k
    expr_ty formatted_value = _PyAST_FormattedValue(
1682
26.5k
        expression, conversion_val, format ? (expr_ty) format->result : NULL,
1683
26.5k
        lineno, col_offset, end_lineno,
1684
26.5k
        end_col_offset, arena
1685
26.5k
    );
1686
1687
26.5k
    if (!formatted_value || !debug) {
1688
23.1k
        return formatted_value;
1689
23.1k
    }
1690
1691
    /* Find the non whitespace token after the "=" */
1692
3.42k
    int debug_end_line, debug_end_offset;
1693
3.42k
    PyObject *debug_metadata;
1694
1695
3.42k
    if (conversion) {
1696
100
        debug_end_line = ((expr_ty) conversion->result)->lineno;
1697
100
        debug_end_offset = ((expr_ty) conversion->result)->col_offset;
1698
100
        debug_metadata = conversion->metadata;
1699
100
    }
1700
3.32k
    else if (format) {
1701
1.55k
        debug_end_line = ((expr_ty) format->result)->lineno;
1702
1.55k
        debug_end_offset = ((expr_ty) format->result)->col_offset + 1;
1703
1.55k
        debug_metadata = format->metadata;
1704
1.55k
    }
1705
1.77k
    else {
1706
1.77k
        debug_end_line = end_lineno;
1707
1.77k
        debug_end_offset = end_col_offset;
1708
1.77k
        debug_metadata = closing_brace->metadata;
1709
1.77k
    }
1710
3.42k
    expr_ty debug_text = _PyAST_Constant(debug_metadata, NULL, lineno, col_offset + 1, debug_end_line,
1711
3.42k
                                            debug_end_offset - 1, p->arena);
1712
3.42k
    if (!debug_text) {
1713
0
        return NULL;
1714
0
    }
1715
1716
3.42k
    asdl_expr_seq *values = _Py_asdl_expr_seq_new(2, arena);
1717
3.42k
    if (!values) {
1718
0
        return NULL;
1719
0
    }
1720
3.42k
    asdl_seq_SET(values, 0, debug_text);
1721
3.42k
    asdl_seq_SET(values, 1, formatted_value);
1722
3.42k
    return _PyAST_JoinedStr(values, lineno, col_offset, debug_end_line, debug_end_offset, p->arena);
1723
3.42k
}
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
711
{
1730
711
    Py_ssize_t len = asdl_seq_LEN(strings);
1731
711
    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
711
    PyObject *kind = asdl_seq_GET(strings, 0)->v.Constant.kind;
1738
1739
711
    Py_ssize_t total = 0;
1740
4.56k
    for (Py_ssize_t i = 0; i < len; i++) {
1741
3.85k
        expr_ty elem = asdl_seq_GET(strings, i);
1742
3.85k
        PyObject *bytes = elem->v.Constant.value;
1743
3.85k
        Py_ssize_t part = PyBytes_GET_SIZE(bytes);
1744
3.85k
        if (part > PY_SSIZE_T_MAX - total) {
1745
0
            PyErr_NoMemory();
1746
0
            return NULL;
1747
0
        }
1748
3.85k
        total += part;
1749
3.85k
    }
1750
1751
711
    PyBytesWriter *writer = PyBytesWriter_Create(total);
1752
711
    if (writer == NULL) {
1753
0
        return NULL;
1754
0
    }
1755
711
    char *out = PyBytesWriter_GetData(writer);
1756
1757
4.56k
    for (Py_ssize_t i = 0; i < len; i++) {
1758
3.85k
        expr_ty elem = asdl_seq_GET(strings, i);
1759
3.85k
        PyObject *bytes = elem->v.Constant.value;
1760
3.85k
        Py_ssize_t part = PyBytes_GET_SIZE(bytes);
1761
3.85k
        if (part > 0) {
1762
2.49k
            memcpy(out, PyBytes_AS_STRING(bytes), part);
1763
2.49k
            out += part;
1764
2.49k
        }
1765
3.85k
    }
1766
1767
711
    PyObject *res = PyBytesWriter_Finish(writer);
1768
711
    if (res == NULL) {
1769
0
        return NULL;
1770
0
    }
1771
711
    if (_PyArena_AddPyObject(arena, res) < 0) {
1772
0
        Py_DECREF(res);
1773
0
        return NULL;
1774
0
    }
1775
711
    return _PyAST_Constant(res, kind, lineno, col_offset, end_lineno, end_col_offset, p->arena);
1776
711
}
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
2.61k
{
1783
2.61k
    Py_ssize_t len = asdl_seq_LEN(strings);
1784
2.61k
    assert(len > 1);
1785
1786
2.61k
    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
2.61k
    PyObject *kind = first->v.Constant.kind;
1795
1796
2.61k
    PyUnicodeWriter *writer = PyUnicodeWriter_Create(0);
1797
2.61k
    if (writer == NULL) {
1798
0
        return NULL;
1799
0
    }
1800
1801
10.4k
    for (Py_ssize_t i = 0; i < len; i++) {
1802
7.85k
        expr_ty current_elem = asdl_seq_GET(strings, i);
1803
7.85k
        assert(current_elem->kind == Constant_kind);
1804
1805
7.85k
        if (PyUnicodeWriter_WriteStr(writer,
1806
7.85k
                                     current_elem->v.Constant.value)) {
1807
0
            PyUnicodeWriter_Discard(writer);
1808
0
            return NULL;
1809
0
        }
1810
7.85k
    }
1811
1812
2.61k
    PyObject *final = PyUnicodeWriter_Finish(writer);
1813
2.61k
    if (final == NULL) {
1814
0
        return NULL;
1815
0
    }
1816
2.61k
    if (_PyArena_AddPyObject(p->arena, final) < 0) {
1817
0
        Py_DECREF(final);
1818
0
        return NULL;
1819
0
    }
1820
2.61k
    return _PyAST_Constant(final, kind, lineno, col_offset,
1821
2.61k
                           end_lineno, end_col_offset, arena);
1822
2.61k
}
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
28.9k
{
1829
28.9k
    Py_ssize_t len = asdl_seq_LEN(strings);
1830
28.9k
    assert(len > 0);
1831
1832
28.9k
    Py_ssize_t n_flattened_elements = 0;
1833
88.8k
    for (Py_ssize_t i = 0; i < len; i++) {
1834
59.8k
        expr_ty elem = asdl_seq_GET(strings, i);
1835
59.8k
        switch(elem->kind) {
1836
22.6k
            case JoinedStr_kind:
1837
22.6k
                n_flattened_elements += asdl_seq_LEN(elem->v.JoinedStr.values);
1838
22.6k
                break;
1839
4.88k
            case TemplateStr_kind:
1840
4.88k
                n_flattened_elements += asdl_seq_LEN(elem->v.TemplateStr.values);
1841
4.88k
                break;
1842
32.3k
            default:
1843
32.3k
                n_flattened_elements++;
1844
32.3k
                break;
1845
59.8k
        }
1846
59.8k
    }
1847
1848
1849
28.9k
    asdl_expr_seq* flattened = _Py_asdl_expr_seq_new(n_flattened_elements, p->arena);
1850
28.9k
    if (flattened == NULL) {
1851
0
        return NULL;
1852
0
    }
1853
1854
    /* build flattened list */
1855
28.9k
    Py_ssize_t current_pos = 0;
1856
88.8k
    for (Py_ssize_t i = 0; i < len; i++) {
1857
59.8k
        expr_ty elem = asdl_seq_GET(strings, i);
1858
59.8k
        switch(elem->kind) {
1859
22.6k
            case JoinedStr_kind:
1860
143k
                for (Py_ssize_t j = 0; j < asdl_seq_LEN(elem->v.JoinedStr.values); j++) {
1861
120k
                    expr_ty subvalue = asdl_seq_GET(elem->v.JoinedStr.values, j);
1862
120k
                    if (subvalue == NULL) {
1863
0
                        return NULL;
1864
0
                    }
1865
120k
                    asdl_seq_SET(flattened, current_pos++, subvalue);
1866
120k
                }
1867
22.6k
                break;
1868
22.6k
            case TemplateStr_kind:
1869
24.9k
                for (Py_ssize_t j = 0; j < asdl_seq_LEN(elem->v.TemplateStr.values); j++) {
1870
20.0k
                    expr_ty subvalue = asdl_seq_GET(elem->v.TemplateStr.values, j);
1871
20.0k
                    if (subvalue == NULL) {
1872
0
                        return NULL;
1873
0
                    }
1874
20.0k
                    asdl_seq_SET(flattened, current_pos++, subvalue);
1875
20.0k
                }
1876
4.88k
                break;
1877
32.3k
            default:
1878
32.3k
                asdl_seq_SET(flattened, current_pos++, elem);
1879
32.3k
                break;
1880
59.8k
        }
1881
59.8k
    }
1882
1883
    /* calculate folded element count */
1884
28.9k
    Py_ssize_t n_elements = 0;
1885
28.9k
    int prev_is_constant = 0;
1886
201k
    for (Py_ssize_t i = 0; i < n_flattened_elements; i++) {
1887
172k
        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
172k
        if (elem->kind == Constant_kind &&
1893
172k
            PyUnicode_CheckExact(elem->v.Constant.value) &&
1894
143k
            PyUnicode_GET_LENGTH(elem->v.Constant.value) == 0)
1895
5.11k
            continue;
1896
1897
167k
        if (!prev_is_constant || elem->kind != Constant_kind) {
1898
65.4k
            n_elements++;
1899
65.4k
        }
1900
167k
        prev_is_constant = elem->kind == Constant_kind;
1901
167k
    }
1902
1903
28.9k
    asdl_expr_seq* values = _Py_asdl_expr_seq_new(n_elements, p->arena);
1904
28.9k
    if (values == NULL) {
1905
0
        return NULL;
1906
0
    }
1907
1908
    /* build folded list */
1909
28.9k
    current_pos = 0;
1910
94.7k
    for (Py_ssize_t i = 0; i < n_flattened_elements; i++) {
1911
65.8k
        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
65.8k
        if (elem->kind == Constant_kind) {
1916
36.4k
            if (i + 1 < n_flattened_elements &&
1917
27.0k
                asdl_seq_GET(flattened, i + 1)->kind == Constant_kind) {
1918
12.1k
                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
12.1k
                PyObject *kind = elem->v.Constant.kind;
1927
1928
12.1k
                PyUnicodeWriter *writer = PyUnicodeWriter_Create(0);
1929
12.1k
                if (writer == NULL) {
1930
0
                    return NULL;
1931
0
                }
1932
12.1k
                expr_ty last_elem = elem;
1933
12.1k
                Py_ssize_t j;
1934
131k
                for (j = i; j < n_flattened_elements; j++) {
1935
125k
                    expr_ty current_elem = asdl_seq_GET(flattened, j);
1936
125k
                    if (current_elem->kind == Constant_kind) {
1937
119k
                        if (PyUnicodeWriter_WriteStr(writer,
1938
119k
                                                     current_elem->v.Constant.value)) {
1939
0
                            PyUnicodeWriter_Discard(writer);
1940
0
                            return NULL;
1941
0
                        }
1942
119k
                        last_elem = current_elem;
1943
119k
                    } else {
1944
6.58k
                        break;
1945
6.58k
                    }
1946
125k
                }
1947
12.1k
                i = j - 1;
1948
1949
12.1k
                PyObject *concat_str = PyUnicodeWriter_Finish(writer);
1950
12.1k
                if (concat_str == NULL) {
1951
0
                    return NULL;
1952
0
                }
1953
12.1k
                if (_PyArena_AddPyObject(p->arena, concat_str) < 0) {
1954
0
                    Py_DECREF(concat_str);
1955
0
                    return NULL;
1956
0
                }
1957
12.1k
                elem = _PyAST_Constant(concat_str, kind, first_elem->lineno,
1958
12.1k
                                       first_elem->col_offset,
1959
12.1k
                                       last_elem->end_lineno,
1960
12.1k
                                       last_elem->end_col_offset, p->arena);
1961
12.1k
                if (elem == NULL) {
1962
0
                    return NULL;
1963
0
                }
1964
12.1k
            }
1965
1966
            /* Drop all empty contanst strings */
1967
36.4k
            if (PyUnicode_CheckExact(elem->v.Constant.value) &&
1968
36.4k
                PyUnicode_GET_LENGTH(elem->v.Constant.value) == 0) {
1969
322
                continue;
1970
322
            }
1971
36.4k
        }
1972
1973
65.4k
        asdl_seq_SET(values, current_pos++, elem);
1974
65.4k
    }
1975
1976
28.9k
    assert(current_pos == n_elements);
1977
28.9k
    return values;
1978
28.9k
}
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
24.4k
{
1985
24.4k
    asdl_expr_seq *values = _build_concatenated_str(p, strings, lineno,
1986
24.4k
        col_offset, end_lineno, end_col_offset, arena);
1987
24.4k
    if (!values) {
1988
0
        return NULL;
1989
0
    }
1990
24.4k
    return _PyAST_JoinedStr(values, lineno, col_offset, end_lineno, end_col_offset, p->arena);
1991
24.4k
}
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
4.50k
{
1998
4.50k
    asdl_expr_seq *values = _build_concatenated_str(p, strings, lineno,
1999
4.50k
        col_offset, end_lineno, end_col_offset, arena);
2000
4.50k
    if (!values) {
2001
0
        return NULL;
2002
0
    }
2003
4.50k
    return _PyAST_TemplateStr(values, lineno, col_offset, end_lineno,
2004
4.50k
        end_col_offset, arena);
2005
4.50k
}
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
93.4k
{
2012
93.4k
    Py_ssize_t len = asdl_seq_LEN(strings);
2013
93.4k
    assert(len > 0);
2014
2015
93.4k
    int f_string_found = 0;
2016
93.4k
    int unicode_string_found = 0;
2017
93.4k
    int bytes_found = 0;
2018
2019
93.4k
    Py_ssize_t i = 0;
2020
226k
    for (i = 0; i < len; i++) {
2021
132k
        expr_ty elem = asdl_seq_GET(strings, i);
2022
132k
        switch(elem->kind) {
2023
99.2k
            case Constant_kind:
2024
99.2k
                if (PyBytes_CheckExact(elem->v.Constant.value)) {
2025
23.9k
                    bytes_found = 1;
2026
75.2k
                } else {
2027
75.2k
                    unicode_string_found = 1;
2028
75.2k
                }
2029
99.2k
                break;
2030
22.6k
            case JoinedStr_kind:
2031
22.6k
                f_string_found = 1;
2032
22.6k
                break;
2033
0
            case TemplateStr_kind:
2034
                // python.gram handles this; we should never get here
2035
0
                assert(0);
2036
0
                break;
2037
10.9k
            default:
2038
10.9k
                f_string_found = 1;
2039
10.9k
                break;
2040
132k
        }
2041
132k
    }
2042
2043
    // Cannot mix unicode and bytes
2044
93.4k
    if ((unicode_string_found || f_string_found) && bytes_found) {
2045
15
        RAISE_SYNTAX_ERROR("cannot mix bytes and nonbytes literals");
2046
15
        return NULL;
2047
15
    }
2048
2049
    // If it's only bytes or only unicode string, do a simple concat
2050
93.4k
    if (!f_string_found) {
2051
68.9k
        if (len == 1) {
2052
65.6k
            return asdl_seq_GET(strings, 0);
2053
65.6k
        }
2054
3.32k
        else if (bytes_found) {
2055
711
            return _build_concatenated_bytes(p, strings, lineno, col_offset,
2056
711
                end_lineno, end_col_offset, arena);
2057
711
        }
2058
2.61k
        else {
2059
2.61k
            return _build_concatenated_unicode(p, strings, lineno, col_offset,
2060
2.61k
                end_lineno, end_col_offset, arena);
2061
2.61k
        }
2062
68.9k
    }
2063
2064
24.4k
    return _build_concatenated_joined_str(p, strings, lineno,
2065
24.4k
        col_offset, end_lineno, end_col_offset, arena);
2066
93.4k
}
2067
2068
static int
2069
_warn_relative_import_of_lazy(Parser *p, asdl_seq *dots, expr_ty module)
2070
1.68k
{
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
1.68k
    if (p->call_invalid_rules) {
2076
465
        return 0;
2077
465
    }
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
1.22k
    Token *last_dot = asdl_seq_GET_UNTYPED(dots, asdl_seq_LEN(dots) - 1);
2082
1.22k
    if (
2083
1.22k
        last_dot->end_lineno == module->lineno
2084
1.22k
        && last_dot->end_col_offset == module->col_offset
2085
1.22k
    ) {
2086
75
        return 0;
2087
75
    }
2088
2089
1.14k
    int count = _PyPegen_seq_count_dots(dots);
2090
1.14k
    char *buf = PyMem_RawMalloc(count + 1);
2091
1.14k
    if (buf == NULL) {
2092
0
        PyErr_NoMemory();
2093
0
        return -1;
2094
0
    }
2095
1.14k
    memset(buf, '.', count);
2096
1.14k
    buf[count] = '\0';
2097
2098
1.14k
    PyObject *msg = PyUnicode_FromFormat(
2099
1.14k
        "'from %s lazy import' is the same as 'from %slazy import'; "
2100
1.14k
        "did you mean 'lazy from %s import'?",
2101
1.14k
        buf, buf, buf);
2102
1.14k
    PyMem_RawFree(buf);
2103
1.14k
    if (msg == NULL) {
2104
0
        return -1;
2105
0
    }
2106
2107
1.14k
    _PyTokenizer_Info info = _PyTokenizer_GetInfo(p->tok);
2108
1.14k
    int res = _PyErr_EmitSyntaxWarning(msg,
2109
1.14k
                                       info.filename,
2110
1.14k
                                       module->lineno,
2111
1.14k
                                       module->col_offset + 1,
2112
1.14k
                                       module->end_lineno,
2113
1.14k
                                       module->end_col_offset + 1,
2114
1.14k
                                       info.module);
2115
1.14k
    Py_DECREF(msg);
2116
1.14k
    return res;
2117
1.14k
}
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
7.31k
{
2125
7.31k
    identifier module = module_name->v.Name.id;
2126
7.31k
    int level = _PyPegen_seq_count_dots(dots);
2127
7.31k
    if (level == 0 && PyUnicode_CompareWithASCIIString(module, "__future__") == 0) {
2128
2.63k
        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
5.51k
        for (Py_ssize_t i = 0; i < asdl_seq_LEN(names); i++) {
2134
2.88k
            alias_ty alias = asdl_seq_GET(names, i);
2135
2.88k
            if (PyUnicode_CompareWithASCIIString(alias->name, "barry_as_FLUFL") == 0) {
2136
10
                p->flags |= PyPARSE_BARRY_AS_BDFL;
2137
10
                p->tok->barry_as_bdfl = 1;
2138
10
            }
2139
2.88k
        }
2140
2.62k
    }
2141
4.68k
    else if (
2142
4.68k
        level > 0
2143
1.83k
        && lazy_token == NULL
2144
1.82k
        && PyUnicode_CompareWithASCIIString(module, "lazy") == 0
2145
4.68k
    ) {
2146
1.68k
        if (_warn_relative_import_of_lazy(p, dots, module_name) < 0) {
2147
0
            return NULL;
2148
0
        }
2149
1.68k
    }
2150
7.31k
    return _PyAST_ImportFrom(module, names, level, lazy_token ? 1 : 0, lineno,
2151
7.31k
                             col_offset, end_lineno, end_col_offset, arena);
2152
7.31k
}
2153
2154
asdl_stmt_seq*
2155
67.6k
_PyPegen_register_stmts(Parser *p, asdl_stmt_seq* stmts) {
2156
67.6k
    if (!p->call_invalid_rules) {
2157
56.6k
        return stmts;
2158
56.6k
    }
2159
10.9k
    Py_ssize_t len = asdl_seq_LEN(stmts);
2160
10.9k
    if (len == 0) {
2161
0
        return stmts;
2162
0
    }
2163
10.9k
    stmt_ty last_stmt = asdl_seq_GET(stmts, len - 1);
2164
10.9k
    if (p->last_stmt_location.lineno > last_stmt->lineno) {
2165
1.14k
        return stmts;
2166
1.14k
    }
2167
9.82k
    p->last_stmt_location.lineno = last_stmt->lineno;
2168
9.82k
    p->last_stmt_location.col_offset = last_stmt->col_offset;
2169
9.82k
    p->last_stmt_location.end_lineno = last_stmt->end_lineno;
2170
9.82k
    p->last_stmt_location.end_col_offset = last_stmt->end_col_offset;
2171
9.82k
    return stmts;
2172
10.9k
}