Coverage Report

Created: 2025-11-24 06:34

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cpython3/Python/ast_unparse.c
Line
Count
Source
1
#include "Python.h"
2
#include "pycore_ast.h"           // expr_ty
3
#include "pycore_pystate.h"       // _PyInterpreterState_GET()
4
#include "pycore_runtime.h"       // _Py_ID()
5
#include <stdbool.h>
6
7
/* This limited unparser is used to convert annotations back to strings
8
 * during compilation rather than being a full AST unparser.
9
 * See ast.unparse for a full unparser (written in Python)
10
 */
11
12
_Py_DECLARE_STR(dbl_open_br, "{{");
13
_Py_DECLARE_STR(dbl_close_br, "}}");
14
15
/* Forward declarations for recursion via helper functions. */
16
static PyObject *
17
expr_as_unicode(expr_ty e, int level);
18
static int
19
append_ast_expr(PyUnicodeWriter *writer, expr_ty e, int level);
20
static int
21
append_templatestr(PyUnicodeWriter *writer, expr_ty e);
22
static int
23
append_joinedstr(PyUnicodeWriter *writer, expr_ty e, bool is_format_spec);
24
static int
25
append_interpolation(PyUnicodeWriter *writer, expr_ty e);
26
static int
27
append_formattedvalue(PyUnicodeWriter *writer, expr_ty e);
28
static int
29
append_ast_slice(PyUnicodeWriter *writer, expr_ty e);
30
31
static int
32
append_char(PyUnicodeWriter *writer, Py_UCS4 ch)
33
28.3k
{
34
28.3k
    return PyUnicodeWriter_WriteChar(writer, ch);
35
28.3k
}
36
37
static int
38
append_charp(PyUnicodeWriter *writer, const char *charp)
39
163k
{
40
163k
    return PyUnicodeWriter_WriteUTF8(writer, charp, -1);
41
163k
}
42
43
11.5k
#define APPEND_CHAR_FINISH(ch)  do { \
44
11.5k
        return append_char(writer, (ch)); \
45
11.5k
    } while (0)
46
47
1.12k
#define APPEND_STR_FINISH(str)  do { \
48
1.12k
        return append_charp(writer, (str)); \
49
1.12k
    } while (0)
50
51
16.8k
#define APPEND_CHAR(ch)  do { \
52
16.8k
        if (-1 == append_char(writer, (ch))) { \
53
0
            return -1; \
54
0
        } \
55
16.8k
    } while (0)
56
57
128k
#define APPEND_STR(str)  do { \
58
128k
        if (-1 == append_charp(writer, (str))) { \
59
0
            return -1; \
60
0
        } \
61
128k
    } while (0)
62
63
259k
#define APPEND_STR_IF(cond, str)  do { \
64
259k
        if ((cond) && -1 == append_charp(writer, (str))) { \
65
0
            return -1; \
66
0
        } \
67
259k
    } while (0)
68
69
14.4k
#define APPEND_STR_IF_NOT_FIRST(str)  do { \
70
14.4k
        APPEND_STR_IF(!first, (str)); \
71
14.4k
        first = false; \
72
14.4k
    } while (0)
73
74
246k
#define APPEND_EXPR(expr, pr)  do { \
75
246k
        if (-1 == append_ast_expr(writer, (expr), (pr))) { \
76
0
            return -1; \
77
0
        } \
78
246k
    } while (0)
79
80
15.0k
#define APPEND(type, value)  do { \
81
15.0k
        if (-1 == append_ast_ ## type(writer, (value))) { \
82
0
            return -1; \
83
0
        } \
84
15.0k
    } while (0)
85
86
static int
87
append_repr(PyUnicodeWriter *writer, PyObject *obj)
88
90.2k
{
89
90.2k
    PyObject *repr = PyObject_Repr(obj);
90
90.2k
    if (!repr) {
91
0
        return -1;
92
0
    }
93
94
90.2k
    if ((PyFloat_CheckExact(obj) && isinf(PyFloat_AS_DOUBLE(obj))) ||
95
89.1k
        PyComplex_CheckExact(obj))
96
8.27k
    {
97
8.27k
        _Py_DECLARE_STR(str_replace_inf, "1e309");  // evaluates to inf
98
8.27k
        PyObject *new_repr = PyUnicode_Replace(
99
8.27k
            repr,
100
8.27k
            &_Py_ID(inf),
101
8.27k
            &_Py_STR(str_replace_inf),
102
8.27k
            -1
103
8.27k
        );
104
8.27k
        Py_DECREF(repr);
105
8.27k
        if (!new_repr) {
106
0
            return -1;
107
0
        }
108
8.27k
        repr = new_repr;
109
8.27k
    }
110
111
90.2k
    int ret = PyUnicodeWriter_WriteStr(writer, repr);
112
90.2k
    Py_DECREF(repr);
113
90.2k
    return ret;
114
90.2k
}
115
116
/* Priority levels */
117
118
enum {
119
    PR_TUPLE,
120
    PR_TEST,            /* 'if'-'else', 'lambda' */
121
    PR_OR,              /* 'or' */
122
    PR_AND,             /* 'and' */
123
    PR_NOT,             /* 'not' */
124
    PR_CMP,             /* '<', '>', '==', '>=', '<=', '!=',
125
                           'in', 'not in', 'is', 'is not' */
126
    PR_EXPR,
127
    PR_BOR = PR_EXPR,   /* '|' */
128
    PR_BXOR,            /* '^' */
129
    PR_BAND,            /* '&' */
130
    PR_SHIFT,           /* '<<', '>>' */
131
    PR_ARITH,           /* '+', '-' */
132
    PR_TERM,            /* '*', '@', '/', '%', '//' */
133
    PR_FACTOR,          /* unary '+', '-', '~' */
134
    PR_POWER,           /* '**' */
135
    PR_AWAIT,           /* 'await' */
136
    PR_ATOM,
137
};
138
139
static int
140
append_ast_boolop(PyUnicodeWriter *writer, expr_ty e, int level)
141
267
{
142
267
    Py_ssize_t i, value_count;
143
267
    asdl_expr_seq *values;
144
267
    const char *op = (e->v.BoolOp.op == And) ? " and " : " or ";
145
267
    int pr = (e->v.BoolOp.op == And) ? PR_AND : PR_OR;
146
147
267
    APPEND_STR_IF(level > pr, "(");
148
149
267
    values = e->v.BoolOp.values;
150
267
    value_count = asdl_seq_LEN(values);
151
152
2.54k
    for (i = 0; i < value_count; ++i) {
153
2.27k
        APPEND_STR_IF(i > 0, op);
154
2.27k
        APPEND_EXPR((expr_ty)asdl_seq_GET(values, i), pr + 1);
155
2.27k
    }
156
157
267
    APPEND_STR_IF(level > pr, ")");
158
267
    return 0;
159
267
}
160
161
static int
162
append_ast_binop(PyUnicodeWriter *writer, expr_ty e, int level)
163
89.9k
{
164
89.9k
    const char *op;
165
89.9k
    int pr;
166
89.9k
    bool rassoc = false;  /* is right-associative? */
167
168
89.9k
    switch (e->v.BinOp.op) {
169
7.79k
    case Add: op = " + "; pr = PR_ARITH; break;
170
19.6k
    case Sub: op = " - "; pr = PR_ARITH; break;
171
14.2k
    case Mult: op = " * "; pr = PR_TERM; break;
172
2.87k
    case MatMult: op = " @ "; pr = PR_TERM; break;
173
10.0k
    case Div: op = " / "; pr = PR_TERM; break;
174
6.02k
    case Mod: op = " % "; pr = PR_TERM; break;
175
242
    case LShift: op = " << "; pr = PR_SHIFT; break;
176
505
    case RShift: op = " >> "; pr = PR_SHIFT; break;
177
1.25k
    case BitOr: op = " | "; pr = PR_BOR; break;
178
17.5k
    case BitXor: op = " ^ "; pr = PR_BXOR; break;
179
951
    case BitAnd: op = " & "; pr = PR_BAND; break;
180
1.08k
    case FloorDiv: op = " // "; pr = PR_TERM; break;
181
7.83k
    case Pow: op = " ** "; pr = PR_POWER; rassoc = true; break;
182
0
    default:
183
0
        PyErr_SetString(PyExc_SystemError,
184
0
                        "unknown binary operator");
185
0
        return -1;
186
89.9k
    }
187
188
89.9k
    APPEND_STR_IF(level > pr, "(");
189
89.9k
    APPEND_EXPR(e->v.BinOp.left, pr + rassoc);
190
89.9k
    APPEND_STR(op);
191
89.9k
    APPEND_EXPR(e->v.BinOp.right, pr + !rassoc);
192
89.9k
    APPEND_STR_IF(level > pr, ")");
193
89.9k
    return 0;
194
89.9k
}
195
196
static int
197
append_ast_unaryop(PyUnicodeWriter *writer, expr_ty e, int level)
198
16.7k
{
199
16.7k
    const char *op;
200
16.7k
    int pr;
201
202
16.7k
    switch (e->v.UnaryOp.op) {
203
215
    case Invert: op = "~"; pr = PR_FACTOR; break;
204
2
    case Not: op = "not "; pr = PR_NOT; break;
205
11.2k
    case UAdd: op = "+"; pr = PR_FACTOR; break;
206
5.29k
    case USub: op = "-"; pr = PR_FACTOR; break;
207
0
    default:
208
0
        PyErr_SetString(PyExc_SystemError,
209
0
                        "unknown unary operator");
210
0
        return -1;
211
16.7k
    }
212
213
16.7k
    APPEND_STR_IF(level > pr, "(");
214
16.7k
    APPEND_STR(op);
215
16.7k
    APPEND_EXPR(e->v.UnaryOp.operand, pr);
216
16.7k
    APPEND_STR_IF(level > pr, ")");
217
16.7k
    return 0;
218
16.7k
}
219
220
static int
221
append_ast_arg(PyUnicodeWriter *writer, arg_ty arg)
222
6.74k
{
223
6.74k
    if (PyUnicodeWriter_WriteStr(writer, arg->arg) < 0) {
224
0
        return -1;
225
0
    }
226
6.74k
    if (arg->annotation) {
227
0
        APPEND_STR(": ");
228
0
        APPEND_EXPR(arg->annotation, PR_TEST);
229
0
    }
230
6.74k
    return 0;
231
6.74k
}
232
233
static int
234
append_ast_args(PyUnicodeWriter *writer, arguments_ty args)
235
5.11k
{
236
5.11k
    bool first;
237
5.11k
    Py_ssize_t i, di, arg_count, posonlyarg_count, default_count;
238
239
5.11k
    first = true;
240
241
    /* positional-only and positional arguments with defaults */
242
5.11k
    posonlyarg_count = asdl_seq_LEN(args->posonlyargs);
243
5.11k
    arg_count = asdl_seq_LEN(args->args);
244
5.11k
    default_count = asdl_seq_LEN(args->defaults);
245
8.26k
    for (i = 0; i < posonlyarg_count + arg_count; i++) {
246
3.14k
        APPEND_STR_IF_NOT_FIRST(", ");
247
3.14k
        if (i < posonlyarg_count){
248
582
            APPEND(arg, (arg_ty)asdl_seq_GET(args->posonlyargs, i));
249
2.56k
        } else {
250
2.56k
            APPEND(arg, (arg_ty)asdl_seq_GET(args->args, i-posonlyarg_count));
251
2.56k
        }
252
253
3.14k
        di = i - posonlyarg_count - arg_count + default_count;
254
3.14k
        if (di >= 0) {
255
870
            APPEND_CHAR('=');
256
870
            APPEND_EXPR((expr_ty)asdl_seq_GET(args->defaults, di), PR_TEST);
257
870
        }
258
3.14k
        if (posonlyarg_count && i + 1 == posonlyarg_count) {
259
291
            APPEND_STR(", /");
260
291
        }
261
3.14k
    }
262
263
    /* vararg, or bare '*' if no varargs but keyword-only arguments present */
264
5.11k
    if (args->vararg || asdl_seq_LEN(args->kwonlyargs)) {
265
2.05k
        APPEND_STR_IF_NOT_FIRST(", ");
266
2.05k
        APPEND_STR("*");
267
2.05k
        if (args->vararg) {
268
1.37k
            APPEND(arg, args->vararg);
269
1.37k
        }
270
2.05k
    }
271
272
    /* keyword-only arguments */
273
5.11k
    arg_count = asdl_seq_LEN(args->kwonlyargs);
274
5.11k
    default_count = asdl_seq_LEN(args->kw_defaults);
275
6.73k
    for (i = 0; i < arg_count; i++) {
276
1.61k
        APPEND_STR_IF_NOT_FIRST(", ");
277
1.61k
        APPEND(arg, (arg_ty)asdl_seq_GET(args->kwonlyargs, i));
278
279
1.61k
        di = i - arg_count + default_count;
280
1.61k
        if (di >= 0) {
281
1.61k
            expr_ty default_ = (expr_ty)asdl_seq_GET(args->kw_defaults, di);
282
1.61k
            if (default_) {
283
149
                APPEND_CHAR('=');
284
149
                APPEND_EXPR(default_, PR_TEST);
285
149
            }
286
1.61k
        }
287
1.61k
    }
288
289
    /* **kwargs */
290
5.11k
    if (args->kwarg) {
291
608
        APPEND_STR_IF_NOT_FIRST(", ");
292
608
        APPEND_STR("**");
293
608
        APPEND(arg, args->kwarg);
294
608
    }
295
296
5.11k
    return 0;
297
5.11k
}
298
299
static int
300
append_ast_lambda(PyUnicodeWriter *writer, expr_ty e, int level)
301
5.11k
{
302
5.11k
    APPEND_STR_IF(level > PR_TEST, "(");
303
5.11k
    Py_ssize_t n_positional = (asdl_seq_LEN(e->v.Lambda.args->args) +
304
5.11k
                               asdl_seq_LEN(e->v.Lambda.args->posonlyargs));
305
5.11k
    APPEND_STR(n_positional ? "lambda " : "lambda");
306
5.11k
    APPEND(args, e->v.Lambda.args);
307
5.11k
    APPEND_STR(": ");
308
5.11k
    APPEND_EXPR(e->v.Lambda.body, PR_TEST);
309
5.11k
    APPEND_STR_IF(level > PR_TEST, ")");
310
5.11k
    return 0;
311
5.11k
}
312
313
static int
314
append_ast_ifexp(PyUnicodeWriter *writer, expr_ty e, int level)
315
157
{
316
157
    APPEND_STR_IF(level > PR_TEST, "(");
317
157
    APPEND_EXPR(e->v.IfExp.body, PR_TEST + 1);
318
157
    APPEND_STR(" if ");
319
157
    APPEND_EXPR(e->v.IfExp.test, PR_TEST + 1);
320
157
    APPEND_STR(" else ");
321
157
    APPEND_EXPR(e->v.IfExp.orelse, PR_TEST);
322
157
    APPEND_STR_IF(level > PR_TEST, ")");
323
157
    return 0;
324
157
}
325
326
static int
327
append_ast_dict(PyUnicodeWriter *writer, expr_ty e)
328
55
{
329
55
    Py_ssize_t i, value_count;
330
55
    expr_ty key_node;
331
332
55
    APPEND_CHAR('{');
333
55
    value_count = asdl_seq_LEN(e->v.Dict.values);
334
335
136
    for (i = 0; i < value_count; i++) {
336
81
        APPEND_STR_IF(i > 0, ", ");
337
81
        key_node = (expr_ty)asdl_seq_GET(e->v.Dict.keys, i);
338
81
        if (key_node != NULL) {
339
81
            APPEND_EXPR(key_node, PR_TEST);
340
81
            APPEND_STR(": ");
341
81
            APPEND_EXPR((expr_ty)asdl_seq_GET(e->v.Dict.values, i), PR_TEST);
342
81
        }
343
0
        else {
344
0
            APPEND_STR("**");
345
0
            APPEND_EXPR((expr_ty)asdl_seq_GET(e->v.Dict.values, i), PR_EXPR);
346
0
        }
347
81
    }
348
349
55
    APPEND_CHAR_FINISH('}');
350
55
}
351
352
static int
353
append_ast_set(PyUnicodeWriter *writer, expr_ty e)
354
382
{
355
382
    Py_ssize_t i, elem_count;
356
357
382
    APPEND_CHAR('{');
358
382
    elem_count = asdl_seq_LEN(e->v.Set.elts);
359
1.56k
    for (i = 0; i < elem_count; i++) {
360
1.18k
        APPEND_STR_IF(i > 0, ", ");
361
1.18k
        APPEND_EXPR((expr_ty)asdl_seq_GET(e->v.Set.elts, i), PR_TEST);
362
1.18k
    }
363
364
382
    APPEND_CHAR_FINISH('}');
365
382
}
366
367
static int
368
append_ast_list(PyUnicodeWriter *writer, expr_ty e)
369
23
{
370
23
    Py_ssize_t i, elem_count;
371
372
23
    APPEND_CHAR('[');
373
23
    elem_count = asdl_seq_LEN(e->v.List.elts);
374
42
    for (i = 0; i < elem_count; i++) {
375
19
        APPEND_STR_IF(i > 0, ", ");
376
19
        APPEND_EXPR((expr_ty)asdl_seq_GET(e->v.List.elts, i), PR_TEST);
377
19
    }
378
379
23
    APPEND_CHAR_FINISH(']');
380
23
}
381
382
static int
383
append_ast_tuple(PyUnicodeWriter *writer, expr_ty e, int level)
384
2.22k
{
385
2.22k
    Py_ssize_t i, elem_count;
386
387
2.22k
    elem_count = asdl_seq_LEN(e->v.Tuple.elts);
388
389
2.22k
    if (elem_count == 0) {
390
651
        APPEND_STR_FINISH("()");
391
651
    }
392
393
1.57k
    APPEND_STR_IF(level > PR_TUPLE, "(");
394
395
11.8k
    for (i = 0; i < elem_count; i++) {
396
10.2k
        APPEND_STR_IF(i > 0, ", ");
397
10.2k
        APPEND_EXPR((expr_ty)asdl_seq_GET(e->v.Tuple.elts, i), PR_TEST);
398
10.2k
    }
399
400
1.57k
    APPEND_STR_IF(elem_count == 1, ",");
401
1.57k
    APPEND_STR_IF(level > PR_TUPLE, ")");
402
1.57k
    return 0;
403
1.57k
}
404
405
static int
406
append_ast_comprehension(PyUnicodeWriter *writer, comprehension_ty gen)
407
288
{
408
288
    Py_ssize_t i, if_count;
409
410
288
    APPEND_STR(gen->is_async ? " async for " : " for ");
411
288
    APPEND_EXPR(gen->target, PR_TUPLE);
412
288
    APPEND_STR(" in ");
413
288
    APPEND_EXPR(gen->iter, PR_TEST + 1);
414
415
288
    if_count = asdl_seq_LEN(gen->ifs);
416
584
    for (i = 0; i < if_count; i++) {
417
296
        APPEND_STR(" if ");
418
296
        APPEND_EXPR((expr_ty)asdl_seq_GET(gen->ifs, i), PR_TEST + 1);
419
296
    }
420
288
    return 0;
421
288
}
422
423
static int
424
append_ast_comprehensions(PyUnicodeWriter *writer, asdl_comprehension_seq *comprehensions)
425
159
{
426
159
    Py_ssize_t i, gen_count;
427
159
    gen_count = asdl_seq_LEN(comprehensions);
428
429
447
    for (i = 0; i < gen_count; i++) {
430
288
        APPEND(comprehension, (comprehension_ty)asdl_seq_GET(comprehensions, i));
431
288
    }
432
433
159
    return 0;
434
159
}
435
436
static int
437
append_ast_genexp(PyUnicodeWriter *writer, expr_ty e)
438
61
{
439
61
    APPEND_CHAR('(');
440
61
    APPEND_EXPR(e->v.GeneratorExp.elt, PR_TEST);
441
61
    APPEND(comprehensions, e->v.GeneratorExp.generators);
442
61
    APPEND_CHAR_FINISH(')');
443
61
}
444
445
static int
446
append_ast_listcomp(PyUnicodeWriter *writer, expr_ty e)
447
0
{
448
0
    APPEND_CHAR('[');
449
0
    APPEND_EXPR(e->v.ListComp.elt, PR_TEST);
450
0
    APPEND(comprehensions, e->v.ListComp.generators);
451
0
    APPEND_CHAR_FINISH(']');
452
0
}
453
454
static int
455
append_ast_setcomp(PyUnicodeWriter *writer, expr_ty e)
456
97
{
457
97
    APPEND_CHAR('{');
458
97
    APPEND_EXPR(e->v.SetComp.elt, PR_TEST);
459
97
    APPEND(comprehensions, e->v.SetComp.generators);
460
97
    APPEND_CHAR_FINISH('}');
461
97
}
462
463
static int
464
append_ast_dictcomp(PyUnicodeWriter *writer, expr_ty e)
465
1
{
466
1
    APPEND_CHAR('{');
467
1
    APPEND_EXPR(e->v.DictComp.key, PR_TEST);
468
1
    APPEND_STR(": ");
469
1
    APPEND_EXPR(e->v.DictComp.value, PR_TEST);
470
1
    APPEND(comprehensions, e->v.DictComp.generators);
471
1
    APPEND_CHAR_FINISH('}');
472
1
}
473
474
static int
475
append_ast_compare(PyUnicodeWriter *writer, expr_ty e, int level)
476
805
{
477
805
    const char *op;
478
805
    Py_ssize_t i, comparator_count;
479
805
    asdl_expr_seq *comparators;
480
805
    asdl_int_seq *ops;
481
482
805
    APPEND_STR_IF(level > PR_CMP, "(");
483
484
805
    comparators = e->v.Compare.comparators;
485
805
    ops = e->v.Compare.ops;
486
805
    comparator_count = asdl_seq_LEN(comparators);
487
805
    assert(comparator_count > 0);
488
805
    assert(comparator_count == asdl_seq_LEN(ops));
489
490
805
    APPEND_EXPR(e->v.Compare.left, PR_CMP + 1);
491
492
2.92k
    for (i = 0; i < comparator_count; i++) {
493
2.11k
        switch ((cmpop_ty)asdl_seq_GET(ops, i)) {
494
18
        case Eq:
495
18
            op = " == ";
496
18
            break;
497
8
        case NotEq:
498
8
            op = " != ";
499
8
            break;
500
1.04k
        case Lt:
501
1.04k
            op = " < ";
502
1.04k
            break;
503
94
        case LtE:
504
94
            op = " <= ";
505
94
            break;
506
324
        case Gt:
507
324
            op = " > ";
508
324
            break;
509
17
        case GtE:
510
17
            op = " >= ";
511
17
            break;
512
268
        case Is:
513
268
            op = " is ";
514
268
            break;
515
0
        case IsNot:
516
0
            op = " is not ";
517
0
            break;
518
344
        case In:
519
344
            op = " in ";
520
344
            break;
521
0
        case NotIn:
522
0
            op = " not in ";
523
0
            break;
524
0
        default:
525
0
            PyErr_SetString(PyExc_SystemError,
526
0
                            "unexpected comparison kind");
527
0
            return -1;
528
2.11k
        }
529
530
2.11k
        APPEND_STR(op);
531
2.11k
        APPEND_EXPR((expr_ty)asdl_seq_GET(comparators, i), PR_CMP + 1);
532
2.11k
    }
533
534
805
    APPEND_STR_IF(level > PR_CMP, ")");
535
805
    return 0;
536
805
}
537
538
static int
539
append_ast_keyword(PyUnicodeWriter *writer, keyword_ty kw)
540
2.76k
{
541
2.76k
    if (kw->arg == NULL) {
542
503
        APPEND_STR("**");
543
503
    }
544
2.26k
    else {
545
2.26k
        if (-1 == PyUnicodeWriter_WriteStr(writer, kw->arg)) {
546
0
            return -1;
547
0
        }
548
549
2.26k
        APPEND_CHAR('=');
550
2.26k
    }
551
552
2.76k
    APPEND_EXPR(kw->value, PR_TEST);
553
2.76k
    return 0;
554
2.76k
}
555
556
static int
557
append_ast_call(PyUnicodeWriter *writer, expr_ty e)
558
4.64k
{
559
4.64k
    bool first;
560
4.64k
    Py_ssize_t i, arg_count, kw_count;
561
4.64k
    expr_ty expr;
562
563
4.64k
    APPEND_EXPR(e->v.Call.func, PR_ATOM);
564
565
4.64k
    arg_count = asdl_seq_LEN(e->v.Call.args);
566
4.64k
    kw_count = asdl_seq_LEN(e->v.Call.keywords);
567
4.64k
    if (arg_count == 1 && kw_count == 0) {
568
1.31k
        expr = (expr_ty)asdl_seq_GET(e->v.Call.args, 0);
569
1.31k
        if (expr->kind == GeneratorExp_kind) {
570
            /* Special case: a single generator expression. */
571
49
            return append_ast_genexp(writer, expr);
572
49
        }
573
1.31k
    }
574
575
4.59k
    APPEND_CHAR('(');
576
577
4.59k
    first = true;
578
8.82k
    for (i = 0; i < arg_count; i++) {
579
4.22k
        APPEND_STR_IF_NOT_FIRST(", ");
580
4.22k
        APPEND_EXPR((expr_ty)asdl_seq_GET(e->v.Call.args, i), PR_TEST);
581
4.22k
    }
582
583
7.36k
    for (i = 0; i < kw_count; i++) {
584
2.76k
        APPEND_STR_IF_NOT_FIRST(", ");
585
2.76k
        APPEND(keyword, (keyword_ty)asdl_seq_GET(e->v.Call.keywords, i));
586
2.76k
    }
587
588
4.59k
    APPEND_CHAR_FINISH(')');
589
4.59k
}
590
591
static PyObject *
592
escape_braces(PyObject *orig)
593
9.82k
{
594
9.82k
    PyObject *temp;
595
9.82k
    PyObject *result;
596
9.82k
    temp = PyUnicode_Replace(orig, _Py_LATIN1_CHR('{'),
597
9.82k
                             &_Py_STR(dbl_open_br), -1);
598
9.82k
    if (!temp) {
599
0
        return NULL;
600
0
    }
601
9.82k
    result = PyUnicode_Replace(temp, _Py_LATIN1_CHR('}'),
602
9.82k
                               &_Py_STR(dbl_close_br), -1);
603
9.82k
    Py_DECREF(temp);
604
9.82k
    return result;
605
9.82k
}
606
607
static int
608
append_fstring_unicode(PyUnicodeWriter *writer, PyObject *unicode)
609
9.82k
{
610
9.82k
    PyObject *escaped;
611
9.82k
    int result = -1;
612
9.82k
    escaped = escape_braces(unicode);
613
9.82k
    if (escaped) {
614
9.82k
        result = PyUnicodeWriter_WriteStr(writer, escaped);
615
9.82k
        Py_DECREF(escaped);
616
9.82k
    }
617
9.82k
    return result;
618
9.82k
}
619
620
static int
621
append_fstring_element(PyUnicodeWriter *writer, expr_ty e, bool is_format_spec)
622
15.7k
{
623
15.7k
    switch (e->kind) {
624
9.82k
    case Constant_kind:
625
9.82k
        return append_fstring_unicode(writer, e->v.Constant.value);
626
681
    case JoinedStr_kind:
627
681
        return append_joinedstr(writer, e, is_format_spec);
628
0
    case TemplateStr_kind:
629
0
        return append_templatestr(writer, e);
630
4.83k
    case FormattedValue_kind:
631
4.83k
        return append_formattedvalue(writer, e);
632
388
    case Interpolation_kind:
633
388
        return append_interpolation(writer, e);
634
0
    default:
635
0
        PyErr_SetString(PyExc_SystemError,
636
0
                        "unknown expression kind inside f-string or t-string");
637
0
        return -1;
638
15.7k
    }
639
15.7k
}
640
641
/* Build body separately to enable wrapping the entire stream of Strs,
642
   Constants and FormattedValues in one opening and one closing quote. */
643
static PyObject *
644
build_ftstring_body(asdl_expr_seq *values, bool is_format_spec)
645
6.43k
{
646
6.43k
    PyUnicodeWriter *body_writer = PyUnicodeWriter_Create(256);
647
6.43k
    if (body_writer == NULL) {
648
0
        return NULL;
649
0
    }
650
651
6.43k
    Py_ssize_t value_count = asdl_seq_LEN(values);
652
21.4k
    for (Py_ssize_t i = 0; i < value_count; ++i) {
653
15.0k
        if (-1 == append_fstring_element(body_writer,
654
15.0k
                                         (expr_ty)asdl_seq_GET(values, i),
655
15.0k
                                         is_format_spec
656
15.0k
                                         )) {
657
0
            PyUnicodeWriter_Discard(body_writer);
658
0
            return NULL;
659
0
        }
660
15.0k
    }
661
662
6.43k
    return PyUnicodeWriter_Finish(body_writer);
663
6.43k
}
664
665
static int
666
append_templatestr(PyUnicodeWriter *writer, expr_ty e)
667
261
{
668
261
    int result = -1;
669
261
    PyObject *body = build_ftstring_body(e->v.TemplateStr.values, false);
670
261
    if (!body) {
671
0
        return -1;
672
0
    }
673
674
261
    if (-1 != append_charp(writer, "t") &&
675
261
        -1 != append_repr(writer, body))
676
261
    {
677
261
        result = 0;
678
261
    }
679
261
    Py_DECREF(body);
680
261
    return result;
681
261
}
682
683
static int
684
append_joinedstr(PyUnicodeWriter *writer, expr_ty e, bool is_format_spec)
685
6.17k
{
686
6.17k
    int result = -1;
687
6.17k
    PyObject *body = build_ftstring_body(e->v.JoinedStr.values, is_format_spec);
688
6.17k
    if (!body) {
689
0
        return -1;
690
0
    }
691
692
6.17k
    if (!is_format_spec) {
693
5.49k
        if (-1 != append_charp(writer, "f") &&
694
5.49k
            -1 != append_repr(writer, body))
695
5.49k
        {
696
5.49k
            result = 0;
697
5.49k
        }
698
5.49k
    }
699
681
    else {
700
681
        result = PyUnicodeWriter_WriteStr(writer, body);
701
681
    }
702
6.17k
    Py_DECREF(body);
703
6.17k
    return result;
704
6.17k
}
705
706
static int
707
append_interpolation_str(PyUnicodeWriter *writer, PyObject *str)
708
5.21k
{
709
5.21k
    const char *outer_brace = "{";
710
5.21k
    if (PyUnicode_Find(str, _Py_LATIN1_CHR('{'), 0, 1, 1) == 0) {
711
        /* Expression starts with a brace, split it with a space from the outer
712
           one. */
713
12
        outer_brace = "{ ";
714
12
    }
715
5.21k
    if (-1 == append_charp(writer, outer_brace)) {
716
0
        return -1;
717
0
    }
718
5.21k
    if (-1 == PyUnicodeWriter_WriteStr(writer, str)) {
719
0
        return -1;
720
0
    }
721
5.21k
    return 0;
722
5.21k
}
723
724
static int
725
append_interpolation_value(PyUnicodeWriter *writer, expr_ty e)
726
4.83k
{
727
    /* Grammar allows PR_TUPLE, but use >PR_TEST for adding parenthesis
728
       around a lambda with ':' */
729
4.83k
    PyObject *temp_fv_str = expr_as_unicode(e, PR_TEST + 1);
730
4.83k
    if (!temp_fv_str) {
731
0
        return -1;
732
0
    }
733
4.83k
    int result = append_interpolation_str(writer, temp_fv_str);
734
4.83k
    Py_DECREF(temp_fv_str);
735
4.83k
    return result;
736
4.83k
}
737
738
static int
739
append_interpolation_conversion(PyUnicodeWriter *writer, int conversion)
740
5.21k
{
741
5.21k
    if (conversion < 0) {
742
1.59k
        return 0;
743
1.59k
    }
744
745
3.62k
    const char *conversion_str;
746
3.62k
    switch (conversion) {
747
401
    case 'a':
748
401
        conversion_str = "!a";
749
401
        break;
750
959
    case 'r':
751
959
        conversion_str = "!r";
752
959
        break;
753
2.26k
    case 's':
754
2.26k
        conversion_str = "!s";
755
2.26k
        break;
756
0
    default:
757
0
        PyErr_SetString(PyExc_SystemError,
758
0
                        "unknown f-value conversion kind");
759
0
        return -1;
760
3.62k
    }
761
3.62k
    APPEND_STR(conversion_str);
762
3.62k
    return 0;
763
3.62k
}
764
765
static int
766
append_interpolation_format_spec(PyUnicodeWriter *writer, expr_ty e)
767
5.21k
{
768
5.21k
    if (e) {
769
681
        if (-1 == PyUnicodeWriter_WriteChar(writer, ':') ||
770
681
            -1 == append_fstring_element(writer, e, true))
771
0
        {
772
0
            return -1;
773
0
        }
774
681
    }
775
5.21k
    return 0;
776
5.21k
}
777
778
static int
779
append_interpolation(PyUnicodeWriter *writer, expr_ty e)
780
388
{
781
388
    if (-1 == append_interpolation_str(writer, e->v.Interpolation.str)) {
782
0
        return -1;
783
0
    }
784
785
388
    if (-1 == append_interpolation_conversion(writer, e->v.Interpolation.conversion)) {
786
0
        return -1;
787
0
    }
788
789
388
    if (-1 == append_interpolation_format_spec(writer, e->v.Interpolation.format_spec)) {
790
0
        return -1;
791
0
    }
792
793
388
    APPEND_STR_FINISH("}");
794
388
}
795
796
static int
797
append_formattedvalue(PyUnicodeWriter *writer, expr_ty e)
798
4.83k
{
799
4.83k
    if (-1 == append_interpolation_value(writer, e->v.FormattedValue.value)) {
800
0
        return -1;
801
0
    }
802
803
4.83k
    if (-1 == append_interpolation_conversion(writer, e->v.FormattedValue.conversion)) {
804
0
        return -1;
805
0
    }
806
807
4.83k
    if (-1 == append_interpolation_format_spec(writer, e->v.FormattedValue.format_spec)) {
808
0
        return -1;
809
0
    }
810
811
4.83k
    APPEND_CHAR_FINISH('}');
812
4.83k
}
813
814
static int
815
append_ast_constant(PyUnicodeWriter *writer, PyObject *constant)
816
84.4k
{
817
84.4k
    if (PyTuple_CheckExact(constant)) {
818
0
        Py_ssize_t i, elem_count;
819
820
0
        elem_count = PyTuple_GET_SIZE(constant);
821
0
        APPEND_CHAR('(');
822
0
        for (i = 0; i < elem_count; i++) {
823
0
            APPEND_STR_IF(i > 0, ", ");
824
0
            if (append_ast_constant(writer, PyTuple_GET_ITEM(constant, i)) < 0) {
825
0
                return -1;
826
0
            }
827
0
        }
828
829
0
        APPEND_STR_IF(elem_count == 1, ",");
830
0
        APPEND_CHAR_FINISH(')');
831
0
    }
832
84.4k
    return append_repr(writer, constant);
833
84.4k
}
834
835
static int
836
append_ast_attribute(PyUnicodeWriter *writer, expr_ty e)
837
1.11k
{
838
1.11k
    const char *period;
839
1.11k
    expr_ty v = e->v.Attribute.value;
840
1.11k
    APPEND_EXPR(v, PR_ATOM);
841
842
    /* Special case: integers require a space for attribute access to be
843
       unambiguous. */
844
1.11k
    if (v->kind == Constant_kind && PyLong_CheckExact(v->v.Constant.value)) {
845
46
        period = " .";
846
46
    }
847
1.06k
    else {
848
1.06k
        period = ".";
849
1.06k
    }
850
1.11k
    APPEND_STR(period);
851
852
1.11k
    return PyUnicodeWriter_WriteStr(writer, e->v.Attribute.attr);
853
1.11k
}
854
855
static int
856
append_ast_slice(PyUnicodeWriter *writer, expr_ty e)
857
4.68k
{
858
4.68k
    if (e->v.Slice.lower) {
859
4.27k
        APPEND_EXPR(e->v.Slice.lower, PR_TEST);
860
4.27k
    }
861
862
4.68k
    APPEND_CHAR(':');
863
864
4.68k
    if (e->v.Slice.upper) {
865
3.63k
        APPEND_EXPR(e->v.Slice.upper, PR_TEST);
866
3.63k
    }
867
868
4.68k
    if (e->v.Slice.step) {
869
741
        APPEND_CHAR(':');
870
741
        APPEND_EXPR(e->v.Slice.step, PR_TEST);
871
741
    }
872
4.68k
    return 0;
873
4.68k
}
874
875
static int
876
append_ast_subscript(PyUnicodeWriter *writer, expr_ty e)
877
1.49k
{
878
1.49k
    APPEND_EXPR(e->v.Subscript.value, PR_ATOM);
879
1.49k
    APPEND_CHAR('[');
880
1.49k
    APPEND_EXPR(e->v.Subscript.slice, PR_TUPLE);
881
1.49k
    APPEND_CHAR_FINISH(']');
882
1.49k
}
883
884
static int
885
append_ast_starred(PyUnicodeWriter *writer, expr_ty e)
886
1.41k
{
887
1.41k
    APPEND_CHAR('*');
888
1.41k
    APPEND_EXPR(e->v.Starred.value, PR_EXPR);
889
1.41k
    return 0;
890
1.41k
}
891
892
static int
893
append_ast_yield(PyUnicodeWriter *writer, expr_ty e)
894
0
{
895
0
    if (!e->v.Yield.value) {
896
0
        APPEND_STR_FINISH("(yield)");
897
0
    }
898
899
0
    APPEND_STR("(yield ");
900
0
    APPEND_EXPR(e->v.Yield.value, PR_TEST);
901
0
    APPEND_CHAR_FINISH(')');
902
0
}
903
904
static int
905
append_ast_yield_from(PyUnicodeWriter *writer, expr_ty e)
906
0
{
907
0
    APPEND_STR("(yield from ");
908
0
    APPEND_EXPR(e->v.YieldFrom.value, PR_TEST);
909
0
    APPEND_CHAR_FINISH(')');
910
0
}
911
912
static int
913
append_ast_await(PyUnicodeWriter *writer, expr_ty e, int level)
914
0
{
915
0
    APPEND_STR_IF(level > PR_AWAIT, "(");
916
0
    APPEND_STR("await ");
917
0
    APPEND_EXPR(e->v.Await.value, PR_ATOM);
918
0
    APPEND_STR_IF(level > PR_AWAIT, ")");
919
0
    return 0;
920
0
}
921
922
static int
923
append_named_expr(PyUnicodeWriter *writer, expr_ty e, int level)
924
1
{
925
1
    APPEND_STR_IF(level > PR_TUPLE, "(");
926
1
    APPEND_EXPR(e->v.NamedExpr.target, PR_ATOM);
927
1
    APPEND_STR(" := ");
928
1
    APPEND_EXPR(e->v.NamedExpr.value, PR_ATOM);
929
1
    APPEND_STR_IF(level > PR_TUPLE, ")");
930
1
    return 0;
931
1
}
932
933
static int
934
append_ast_expr(PyUnicodeWriter *writer, expr_ty e, int level)
935
254k
{
936
254k
    switch (e->kind) {
937
267
    case BoolOp_kind:
938
267
        return append_ast_boolop(writer, e, level);
939
89.9k
    case BinOp_kind:
940
89.9k
        return append_ast_binop(writer, e, level);
941
16.7k
    case UnaryOp_kind:
942
16.7k
        return append_ast_unaryop(writer, e, level);
943
5.11k
    case Lambda_kind:
944
5.11k
        return append_ast_lambda(writer, e, level);
945
157
    case IfExp_kind:
946
157
        return append_ast_ifexp(writer, e, level);
947
55
    case Dict_kind:
948
55
        return append_ast_dict(writer, e);
949
382
    case Set_kind:
950
382
        return append_ast_set(writer, e);
951
12
    case GeneratorExp_kind:
952
12
        return append_ast_genexp(writer, e);
953
0
    case ListComp_kind:
954
0
        return append_ast_listcomp(writer, e);
955
97
    case SetComp_kind:
956
97
        return append_ast_setcomp(writer, e);
957
1
    case DictComp_kind:
958
1
        return append_ast_dictcomp(writer, e);
959
0
    case Yield_kind:
960
0
        return append_ast_yield(writer, e);
961
0
    case YieldFrom_kind:
962
0
        return append_ast_yield_from(writer, e);
963
0
    case Await_kind:
964
0
        return append_ast_await(writer, e, level);
965
805
    case Compare_kind:
966
805
        return append_ast_compare(writer, e, level);
967
4.64k
    case Call_kind:
968
4.64k
        return append_ast_call(writer, e);
969
84.5k
    case Constant_kind:
970
84.5k
        if (e->v.Constant.value == Py_Ellipsis) {
971
85
            APPEND_STR_FINISH("...");
972
85
        }
973
84.4k
        if (e->v.Constant.kind != NULL
974
346
            && -1 == PyUnicodeWriter_WriteStr(writer, e->v.Constant.kind)) {
975
0
            return -1;
976
0
        }
977
84.4k
        return append_ast_constant(writer, e->v.Constant.value);
978
5.49k
    case JoinedStr_kind:
979
5.49k
        return append_joinedstr(writer, e, false);
980
261
    case TemplateStr_kind:
981
261
        return append_templatestr(writer, e);
982
0
    case FormattedValue_kind:
983
0
        return append_formattedvalue(writer, e);
984
0
    case Interpolation_kind:
985
0
        return append_interpolation(writer, e);
986
    /* The following exprs can be assignment targets. */
987
1.11k
    case Attribute_kind:
988
1.11k
        return append_ast_attribute(writer, e);
989
1.49k
    case Subscript_kind:
990
1.49k
        return append_ast_subscript(writer, e);
991
1.41k
    case Starred_kind:
992
1.41k
        return append_ast_starred(writer, e);
993
4.68k
    case Slice_kind:
994
4.68k
        return append_ast_slice(writer, e);
995
34.8k
    case Name_kind:
996
34.8k
        return PyUnicodeWriter_WriteStr(writer, e->v.Name.id);
997
23
    case List_kind:
998
23
        return append_ast_list(writer, e);
999
2.22k
    case Tuple_kind:
1000
2.22k
        return append_ast_tuple(writer, e, level);
1001
1
    case NamedExpr_kind:
1002
1
        return append_named_expr(writer, e, level);
1003
    // No default so compiler emits a warning for unhandled cases
1004
254k
    }
1005
0
    PyErr_SetString(PyExc_SystemError,
1006
0
                    "unknown expression kind");
1007
0
    return -1;
1008
254k
}
1009
1010
static PyObject *
1011
expr_as_unicode(expr_ty e, int level)
1012
7.38k
{
1013
7.38k
    PyUnicodeWriter *writer = PyUnicodeWriter_Create(256);
1014
7.38k
    if (writer == NULL) {
1015
0
        return NULL;
1016
0
    }
1017
1018
7.38k
    if (-1 == append_ast_expr(writer, e, level)) {
1019
0
        PyUnicodeWriter_Discard(writer);
1020
0
        return NULL;
1021
0
    }
1022
7.38k
    return PyUnicodeWriter_Finish(writer);
1023
7.38k
}
1024
1025
PyObject *
1026
_PyAST_ExprAsUnicode(expr_ty e)
1027
2.55k
{
1028
2.55k
    return expr_as_unicode(e, PR_TEST);
1029
2.55k
}