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