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