Coverage Report

Created: 2025-07-11 06:59

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