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