LCOV - code coverage report
Current view: top level - Python - ast_unparse.c (source / functions) Hit Total Coverage
Test: CPython 3.12 LCOV report [commit acb105a7c1f] Lines: 392 497 78.9 %
Date: 2022-07-20 13:12:14 Functions: 37 41 90.2 %
Branches: 336 566 59.4 %

           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                 :            : }

Generated by: LCOV version 1.14