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