Coverage Report

Created: 2022-07-08 09:39

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