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