Branch data 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 : : assert(comparator_count > 0);
470 : : 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 [ - + ]: 10 : !(_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 : : }
|