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