LCOV - code coverage report
Current view: | top level - Python - ast.c (source / functions) |  |  | Hit | Total | Coverage
Test: | CPython 3.12 LCOV report [commit 5e6661bce9] |  | Lines: | 10 | 673 | 1.5 %
Date: | 2023-03-20 08:15:36 |  | Functions: | 1 | 23 | 4.3 %
|  |  | Branches: | 8 | 762 | 1.0 %

               Branch data     Line data    Source code
           1                 :            : /*
           2                 :            :  * This file exposes PyAST_Validate interface to check the integrity
           3                 :            :  * of the given abstract syntax tree (potentially constructed manually).
           4                 :            :  */
           5                 :            : #include "Python.h"
           6                 :            : #include "pycore_ast.h"           // asdl_stmt_seq
           7                 :            : #include "pycore_pystate.h"       // _PyThreadState_GET()
           8                 :            :
           9                 :            : #include <assert.h>
          10                 :            : #include <stdbool.h>
          11                 :            :
          12                 :            : struct validator {
          13                 :            :     int recursion_depth;            /* current recursion depth */
          14                 :            :     int recursion_limit;            /* recursion limit */
          15                 :            : };
          16                 :            :
          17                 :            : static int validate_stmts(struct validator *, asdl_stmt_seq *);
          18                 :            : static int validate_exprs(struct validator *, asdl_expr_seq *, expr_context_ty, int);
          19                 :            : static int validate_patterns(struct validator *, asdl_pattern_seq *, int);
          20                 :            : static int _validate_nonempty_seq(asdl_seq *, const char *, const char *);
          21                 :            : static int validate_stmt(struct validator *, stmt_ty);
          22                 :            : static int validate_expr(struct validator *, expr_ty, expr_context_ty);
          23                 :            : static int validate_pattern(struct validator *, pattern_ty, int);
          24                 :            :
          25                 :            : #define VALIDATE_POSITIONS(node) \
          26                 :            :     if (node->lineno > node->end_lineno) { \
          27                 :            :         PyErr_Format(PyExc_ValueError, \
          28                 :            :                      "AST node line range (%d, %d) is not valid", \
          29                 :            :                      node->lineno, node->end_lineno); \
          30                 :            :         return 0; \
          31                 :            :     } \
          32                 :            :     if ((node->lineno < 0 && node->end_lineno != node->lineno) || \
          33                 :            :         (node->col_offset < 0 && node->col_offset != node->end_col_offset)) { \
          34                 :            :         PyErr_Format(PyExc_ValueError, \
          35                 :            :                      "AST node column range (%d, %d) for line range (%d, %d) is not valid", \
          36                 :            :                      node->col_offset, node->end_col_offset, node->lineno, node->end_lineno); \
          37                 :            :         return 0; \
          38                 :            :     } \
          39                 :            :     if (node->lineno == node->end_lineno && node->col_offset > node->end_col_offset) { \
          40                 :            :         PyErr_Format(PyExc_ValueError, \
          41                 :            :                      "line %d, column %d-%d is not a valid range", \
          42                 :            :                      node->lineno, node->col_offset, node->end_col_offset); \
          43                 :            :         return 0; \
          44                 :            :     }
          45                 :            :
          46                 :            : static int
          47                 :          0 : validate_name(PyObject *name)
          48                 :            : {
          49                 :            :     assert(PyUnicode_Check(name));
          50                 :            :     static const char * const forbidden[] = {
          51                 :            :         "None",
          52                 :            :         "True",
          53                 :            :         "False",
          54                 :            :         NULL
          55                 :            :     };
          56         [ #  # ]:          0 :     for (int i = 0; forbidden[i] != NULL; i++) {
          57         [ #  # ]:          0 :         if (_PyUnicode_EqualToASCIIString(name, forbidden[i])) {
          58                 :          0 :             PyErr_Format(PyExc_ValueError, "identifier field can't represent '%s' constant", forbidden[i]);
          59                 :          0 :             return 0;
          60                 :            :         }
          61                 :            :     }
          62                 :          0 :     return 1;
          63                 :            : }
          64                 :            :
          65                 :            : static int
          66                 :          0 : validate_comprehension(struct validator *state, asdl_comprehension_seq *gens)
          67                 :            : {
          68                 :            :     Py_ssize_t i;
          69   [ #  #  #  # ]:          0 :     if (!asdl_seq_LEN(gens)) {
          70                 :          0 :         PyErr_SetString(PyExc_ValueError, "comprehension with no generators");
          71                 :          0 :         return 0;
          72                 :            :     }
          73   [ #  #  #  # ]:          0 :     for (i = 0; i < asdl_seq_LEN(gens); i++) {
          74                 :          0 :         comprehension_ty comp = asdl_seq_GET(gens, i);
          75   [ #  #  #  # ]:          0 :         if (!validate_expr(state, comp->target, Store) ||
          76         [ #  # ]:          0 :             !validate_expr(state, comp->iter, Load) ||
          77                 :          0 :             !validate_exprs(state, comp->ifs, Load, 0))
          78                 :          0 :             return 0;
          79                 :            :     }
          80                 :          0 :     return 1;
          81                 :            : }
          82                 :            :
          83                 :            : static int
          84                 :          0 : validate_keywords(struct validator *state, asdl_keyword_seq *keywords)
          85                 :            : {
          86                 :            :     Py_ssize_t i;
          87   [ #  #  #  # ]:          0 :     for (i = 0; i < asdl_seq_LEN(keywords); i++)
          88         [ #  # ]:          0 :         if (!validate_expr(state, (asdl_seq_GET(keywords, i))->value, Load))
          89                 :          0 :             return 0;
          90                 :          0 :     return 1;
          91                 :            : }
          92                 :            :
          93                 :            : static int
          94                 :          0 : validate_args(struct validator *state, asdl_arg_seq *args)
          95                 :            : {
          96                 :            :     Py_ssize_t i;
          97   [ #  #  #  # ]:          0 :     for (i = 0; i < asdl_seq_LEN(args); i++) {
          98                 :          0 :         arg_ty arg = asdl_seq_GET(args, i);
          99   [ #  #  #  #  :          0 :         VALIDATE_POSITIONS(arg);
              #  #  #  #  #
                 #  #  #  #
                          # ]
         100   [ #  #  #  # ]:          0 :         if (arg->annotation && !validate_expr(state, arg->annotation, Load))
         101                 :          0 :             return 0;
         102                 :            :     }
         103                 :          0 :     return 1;
         104                 :            : }
         105                 :            :
         106                 :            : static const char *
         107                 :          0 : expr_context_name(expr_context_ty ctx)
         108                 :            : {
         109   [ #  #  #  # ]:          0 :     switch (ctx) {
         110                 :          0 :     case Load:
         111                 :          0 :         return "Load";
         112                 :          0 :     case Store:
         113                 :          0 :         return "Store";
         114                 :          0 :     case Del:
         115                 :          0 :         return "Del";
         116                 :            :     // No default case so compiler emits warning for unhandled cases
         117                 :            :     }
         118                 :          0 :     Py_UNREACHABLE();
         119                 :            : }
         120                 :            :
         121                 :            : static int
         122                 :          0 : validate_arguments(struct validator *state, arguments_ty args)
         123                 :            : {
         124   [ #  #  #  # ]:          0 :     if (!validate_args(state, args->posonlyargs) || !validate_args(state, args->args)) {
         125                 :          0 :         return 0;
         126                 :            :     }
         127   [ #  #  #  # ]:          0 :     if (args->vararg && args->vararg->annotation
         128         [ #  # ]:          0 :         && !validate_expr(state, args->vararg->annotation, Load)) {
         129                 :          0 :             return 0;
         130                 :            :     }
         131         [ #  # ]:          0 :     if (!validate_args(state, args->kwonlyargs))
         132                 :          0 :         return 0;
         133   [ #  #  #  # ]:          0 :     if (args->kwarg && args->kwarg->annotation
         134         [ #  # ]:          0 :         && !validate_expr(state, args->kwarg->annotation, Load)) {
         135                 :          0 :             return 0;
         136                 :            :     }
         137   [ #  #  #  #  :          0 :     if (asdl_seq_LEN(args->defaults) > asdl_seq_LEN(args->posonlyargs) + asdl_seq_LEN(args->args)) {
                 #  #  #  # ]
         138                 :          0 :         PyErr_SetString(PyExc_ValueError, "more positional defaults than args on arguments");
         139                 :          0 :         return 0;
         140                 :            :     }
         141   [ #  #  #  #  :          0 :     if (asdl_seq_LEN(args->kw_defaults) != asdl_seq_LEN(args->kwonlyargs)) {
                       #  # ]
         142                 :          0 :         PyErr_SetString(PyExc_ValueError, "length of kwonlyargs is not the same as "
         143                 :            :                         "kw_defaults on arguments");
         144                 :          0 :         return 0;
         145                 :            :     }
         146   [ #  #  #  # ]:          0 :     return validate_exprs(state, args->defaults, Load, 0) && validate_exprs(state, args->kw_defaults, Load, 1);
         147                 :            : }
         148                 :            :
         149                 :            : static int
         150                 :          0 : validate_constant(struct validator *state, PyObject *value)
         151                 :            : {
         152   [ #  #  #  # ]:          0 :     if (value == Py_None || value == Py_Ellipsis)
         153                 :          0 :         return 1;
         154                 :            :
         155         [ #  # ]:          0 :     if (PyLong_CheckExact(value)
         156         [ #  # ]:          0 :             || PyFloat_CheckExact(value)
         157         [ #  # ]:          0 :             || PyComplex_CheckExact(value)
         158         [ #  # ]:          0 :             || PyBool_Check(value)
         159         [ #  # ]:          0 :             || PyUnicode_CheckExact(value)
         160         [ #  # ]:          0 :             || PyBytes_CheckExact(value))
         161                 :          0 :         return 1;
         162                 :            :
         163   [ #  #  #  # ]:          0 :     if (PyTuple_CheckExact(value) || PyFrozenSet_CheckExact(value)) {
         164         [ #  # ]:          0 :         if (++state->recursion_depth > state->recursion_limit) {
         165                 :          0 :             PyErr_SetString(PyExc_RecursionError,
         166                 :            :                             "maximum recursion depth exceeded during compilation");
         167                 :          0 :             return 0;
         168                 :            :         }
         169                 :            :
         170                 :          0 :         PyObject *it = PyObject_GetIter(value);
         171         [ #  # ]:          0 :         if (it == NULL)
         172                 :          0 :             return 0;
         173                 :            :
         174                 :          0 :         while (1) {
         175                 :          0 :             PyObject *item = PyIter_Next(it);
         176         [ #  # ]:          0 :             if (item == NULL) {
         177         [ #  # ]:          0 :                 if (PyErr_Occurred()) {
         178                 :          0 :                     Py_DECREF(it);
         179                 :          0 :                     return 0;
         180                 :            :                 }
         181                 :          0 :                 break;
         182                 :            :             }
         183                 :            :
         184         [ #  # ]:          0 :             if (!validate_constant(state, item)) {
         185                 :          0 :                 Py_DECREF(it);
         186                 :          0 :                 Py_DECREF(item);
         187                 :          0 :                 return 0;
         188                 :            :             }
         189                 :          0 :             Py_DECREF(item);
         190                 :            :         }
         191                 :            :
         192                 :          0 :         Py_DECREF(it);
         193                 :          0 :         --state->recursion_depth;
         194                 :          0 :         return 1;
         195                 :            :     }
         196                 :            :
         197         [ #  # ]:          0 :     if (!PyErr_Occurred()) {
         198                 :          0 :         PyErr_Format(PyExc_TypeError,
         199                 :            :                      "got an invalid type in Constant: %s",
         200                 :            :                      _PyType_Name(Py_TYPE(value)));
         201                 :            :     }
         202                 :          0 :     return 0;
         203                 :            : }
         204                 :            :
         205                 :            : static int
         206                 :          0 : validate_expr(struct validator *state, expr_ty exp, expr_context_ty ctx)
         207                 :            : {
         208   [ #  #  #  #  :          0 :     VALIDATE_POSITIONS(exp);
              #  #  #  #  #
                 #  #  #  #
                          # ]
         209                 :          0 :     int ret = -1;
         210         [ #  # ]:          0 :     if (++state->recursion_depth > state->recursion_limit) {
         211                 :          0 :         PyErr_SetString(PyExc_RecursionError,
         212                 :            :                         "maximum recursion depth exceeded during compilation");
         213                 :          0 :         return 0;
         214                 :            :     }
         215                 :          0 :     int check_ctx = 1;
         216                 :            :     expr_context_ty actual_ctx;
         217                 :            :
         218                 :            :     /* First check expression context. */
         219   [ #  #  #  #  :          0 :     switch (exp->kind) {
                    #  #  # ]
         220                 :          0 :     case Attribute_kind:
         221                 :          0 :         actual_ctx = exp->v.Attribute.ctx;
         222                 :          0 :         break;
         223                 :          0 :     case Subscript_kind:
         224                 :          0 :         actual_ctx = exp->v.Subscript.ctx;
         225                 :          0 :         break;
         226                 :          0 :     case Starred_kind:
         227                 :          0 :         actual_ctx = exp->v.Starred.ctx;
         228                 :          0 :         break;
         229                 :          0 :     case Name_kind:
         230         [ #  # ]:          0 :         if (!validate_name(exp->v.Name.id)) {
         231                 :          0 :             return 0;
         232                 :            :         }
         233                 :          0 :         actual_ctx = exp->v.Name.ctx;
         234                 :          0 :         break;
         235                 :          0 :     case List_kind:
         236                 :          0 :         actual_ctx = exp->v.List.ctx;
         237                 :          0 :         break;
         238                 :          0 :     case Tuple_kind:
         239                 :          0 :         actual_ctx = exp->v.Tuple.ctx;
         240                 :          0 :         break;
         241                 :          0 :     default:
         242         [ #  # ]:          0 :         if (ctx != Load) {
         243                 :          0 :             PyErr_Format(PyExc_ValueError, "expression which can't be "
         244                 :            :                          "assigned to in %s context", expr_context_name(ctx));
         245                 :          0 :             return 0;
         246                 :            :         }
         247                 :          0 :         check_ctx = 0;
         248                 :            :         /* set actual_ctx to prevent gcc warning */
         249                 :          0 :         actual_ctx = 0;
         250                 :            :     }
         251   [ #  #  #  # ]:          0 :     if (check_ctx && actual_ctx != ctx) {
         252                 :          0 :         PyErr_Format(PyExc_ValueError, "expression must have %s context but has %s instead",
         253                 :            :                      expr_context_name(ctx), expr_context_name(actual_ctx));
         254                 :          0 :         return 0;
         255                 :            :     }
         256                 :            :
         257                 :            :     /* Now validate expression. */
         258   [ #  #  #  #  :          0 :     switch (exp->kind) {
              #  #  #  #  #
              #  #  #  #  #
              #  #  #  #  #
              #  #  #  #  #
                 #  #  #  # ]
         259                 :          0 :     case BoolOp_kind:
         260   [ #  #  #  # ]:          0 :         if (asdl_seq_LEN(exp->v.BoolOp.values) < 2) {
         261                 :          0 :             PyErr_SetString(PyExc_ValueError, "BoolOp with less than 2 values");
         262                 :          0 :             return 0;
         263                 :            :         }
         264                 :          0 :         ret = validate_exprs(state, exp->v.BoolOp.values, Load, 0);
         265                 :          0 :         break;
         266                 :          0 :     case BinOp_kind:
         267   [ #  #  #  # ]:          0 :         ret = validate_expr(state, exp->v.BinOp.left, Load) &&
         268                 :          0 :             validate_expr(state, exp->v.BinOp.right, Load);
         269                 :          0 :         break;
         270                 :          0 :     case UnaryOp_kind:
         271                 :          0 :         ret = validate_expr(state, exp->v.UnaryOp.operand, Load);
         272                 :          0 :         break;
         273                 :          0 :     case Lambda_kind:
         274   [ #  #  #  # ]:          0 :         ret = validate_arguments(state, exp->v.Lambda.args) &&
         275                 :          0 :             validate_expr(state, exp->v.Lambda.body, Load);
         276                 :          0 :         break;
         277                 :          0 :     case IfExp_kind:
         278         [ #  # ]:          0 :         ret = validate_expr(state, exp->v.IfExp.test, Load) &&
         279   [ #  #  #  # ]:          0 :             validate_expr(state, exp->v.IfExp.body, Load) &&
         280                 :          0 :             validate_expr(state, exp->v.IfExp.orelse, Load);
         281                 :          0 :         break;
         282                 :          0 :     case Dict_kind:
         283   [ #  #  #  #  :          0 :         if (asdl_seq_LEN(exp->v.Dict.keys) != asdl_seq_LEN(exp->v.Dict.values)) {
                       #  # ]
         284                 :          0 :             PyErr_SetString(PyExc_ValueError,
         285                 :            :                             "Dict doesn't have the same number of keys as values");
         286                 :          0 :             return 0;
         287                 :            :         }
         288                 :            :         /* null_ok=1 for keys expressions to allow dict unpacking to work in
         289                 :            :            dict literals, i.e. ``{**{a:b}}`` */
         290   [ #  #  #  # ]:          0 :         ret = validate_exprs(state, exp->v.Dict.keys, Load, /*null_ok=*/ 1) &&
         291                 :          0 :             validate_exprs(state, exp->v.Dict.values, Load, /*null_ok=*/ 0);
         292                 :          0 :         break;
         293                 :          0 :     case Set_kind:
         294                 :          0 :         ret = validate_exprs(state, exp->v.Set.elts, Load, 0);
         295                 :          0 :         break;
         296                 :            : #define COMP(NAME) \
         297                 :            :         case NAME ## _kind: \
         298                 :            :             ret = validate_comprehension(state, exp->v.NAME.generators) && \
         299                 :            :                 validate_expr(state, exp->v.NAME.elt, Load); \
         300                 :            :             break;
         301   [ #  #  #  # ]:          0 :     COMP(ListComp)
         302   [ #  #  #  # ]:          0 :     COMP(SetComp)
         303   [ #  #  #  # ]:          0 :     COMP(GeneratorExp)
         304                 :            : #undef COMP
         305                 :          0 :     case DictComp_kind:
         306         [ #  # ]:          0 :         ret = validate_comprehension(state, exp->v.DictComp.generators) &&
         307   [ #  #  #  # ]:          0 :             validate_expr(state, exp->v.DictComp.key, Load) &&
         308                 :          0 :             validate_expr(state, exp->v.DictComp.value, Load);
         309                 :          0 :         break;
         310                 :          0 :     case Yield_kind:
         311   [ #  #  #  # ]:          0 :         ret = !exp->v.Yield.value || validate_expr(state, exp->v.Yield.value, Load);
         312                 :          0 :         break;
         313                 :          0 :     case YieldFrom_kind:
         314                 :          0 :         ret = validate_expr(state, exp->v.YieldFrom.value, Load);
         315                 :          0 :         break;
         316                 :          0 :     case Await_kind:
         317                 :          0 :         ret = validate_expr(state, exp->v.Await.value, Load);
         318                 :          0 :         break;
         319                 :          0 :     case Compare_kind:
         320   [ #  #  #  # ]:          0 :         if (!asdl_seq_LEN(exp->v.Compare.comparators)) {
         321                 :          0 :             PyErr_SetString(PyExc_ValueError, "Compare with no comparators");
         322                 :          0 :             return 0;
         323                 :            :         }
         324   [ #  #  #  # ]:          0 :         if (asdl_seq_LEN(exp->v.Compare.comparators) !=
         325         [ #  # ]:          0 :             asdl_seq_LEN(exp->v.Compare.ops)) {
         326                 :          0 :             PyErr_SetString(PyExc_ValueError, "Compare has a different number "
         327                 :            :                             "of comparators and operands");
         328                 :          0 :             return 0;
         329                 :            :         }
         330   [ #  #  #  # ]:          0 :         ret = validate_exprs(state, exp->v.Compare.comparators, Load, 0) &&
         331                 :          0 :             validate_expr(state, exp->v.Compare.left, Load);
         332                 :          0 :         break;
         333                 :          0 :     case Call_kind:
         334         [ #  # ]:          0 :         ret = validate_expr(state, exp->v.Call.func, Load) &&
         335   [ #  #  #  # ]:          0 :             validate_exprs(state, exp->v.Call.args, Load, 0) &&
         336                 :          0 :             validate_keywords(state, exp->v.Call.keywords);
         337                 :          0 :         break;
         338                 :          0 :     case Constant_kind:
         339         [ #  # ]:          0 :         if (!validate_constant(state, exp->v.Constant.value)) {
         340                 :          0 :             return 0;
         341                 :            :         }
         342                 :          0 :         ret = 1;
         343                 :          0 :         break;
         344                 :          0 :     case JoinedStr_kind:
         345                 :          0 :         ret = validate_exprs(state, exp->v.JoinedStr.values, Load, 0);
         346                 :          0 :         break;
         347                 :          0 :     case FormattedValue_kind:
         348         [ #  # ]:          0 :         if (validate_expr(state, exp->v.FormattedValue.value, Load) == 0)
         349                 :          0 :             return 0;
         350         [ #  # ]:          0 :         if (exp->v.FormattedValue.format_spec) {
         351                 :          0 :             ret = validate_expr(state, exp->v.FormattedValue.format_spec, Load);
         352                 :          0 :             break;
         353                 :            :         }
         354                 :          0 :         ret = 1;
         355                 :          0 :         break;
         356                 :          0 :     case Attribute_kind:
         357                 :          0 :         ret = validate_expr(state, exp->v.Attribute.value, Load);
         358                 :          0 :         break;
         359                 :          0 :     case Subscript_kind:
         360   [ #  #  #  # ]:          0 :         ret = validate_expr(state, exp->v.Subscript.slice, Load) &&
         361                 :          0 :             validate_expr(state, exp->v.Subscript.value, Load);
         362                 :          0 :         break;
         363                 :          0 :     case Starred_kind:
         364                 :          0 :         ret = validate_expr(state, exp->v.Starred.value, ctx);
         365                 :          0 :         break;
         366                 :          0 :     case Slice_kind:
         367         [ #  # ]:          0 :         ret = (!exp->v.Slice.lower || validate_expr(state, exp->v.Slice.lower, Load)) &&
         368   [ #  #  #  #  :          0 :             (!exp->v.Slice.upper || validate_expr(state, exp->v.Slice.upper, Load)) &&
                       #  # ]
         369   [ #  #  #  # ]:          0 :             (!exp->v.Slice.step || validate_expr(state, exp->v.Slice.step, Load));
         370                 :          0 :         break;
         371                 :          0 :     case List_kind:
         372                 :          0 :         ret = validate_exprs(state, exp->v.List.elts, ctx, 0);
         373                 :          0 :         break;
         374                 :          0 :     case Tuple_kind:
         375                 :          0 :         ret = validate_exprs(state, exp->v.Tuple.elts, ctx, 0);
         376                 :          0 :         break;
         377                 :          0 :     case NamedExpr_kind:
         378                 :          0 :         ret = validate_expr(state, exp->v.NamedExpr.value, Load);
         379                 :          0 :         break;
         380                 :            :     /* This last case doesn't have any checking. */
         381                 :          0 :     case Name_kind:
         382                 :          0 :         ret = 1;
         383                 :          0 :         break;
         384                 :            :     // No default case so compiler emits warning for unhandled cases
         385                 :            :     }
         386         [ #  # ]:          0 :     if (ret < 0) {
         387                 :          0 :         PyErr_SetString(PyExc_SystemError, "unexpected expression");
         388                 :          0 :         ret = 0;
         389                 :            :     }
         390                 :          0 :     state->recursion_depth--;
         391                 :          0 :     return ret;
         392                 :            : }
         393                 :            :
         394                 :            :
         395                 :            : // Note: the ensure_literal_* functions are only used to validate a restricted
         396                 :            : //       set of non-recursive literals that have already been checked with
         397                 :            : //       validate_expr, so they don't accept the validator state
         398                 :            : static int
         399                 :          0 : ensure_literal_number(expr_ty exp, bool allow_real, bool allow_imaginary)
         400                 :            : {
         401                 :            :     assert(exp->kind == Constant_kind);
         402                 :          0 :     PyObject *value = exp->v.Constant.value;
         403   [ #  #  #  # ]:          0 :     return (allow_real && PyFloat_CheckExact(value)) ||
         404   [ #  #  #  #  :          0 :            (allow_real && PyLong_CheckExact(value)) ||
                       #  # ]
         405         [ #  # ]:          0 :            (allow_imaginary && PyComplex_CheckExact(value));
         406                 :            : }
         407                 :            :
         408                 :            : static int
         409                 :          0 : ensure_literal_negative(expr_ty exp, bool allow_real, bool allow_imaginary)
         410                 :            : {
         411                 :            :     assert(exp->kind == UnaryOp_kind);
         412                 :            :     // Must be negation ...
         413         [ #  # ]:          0 :     if (exp->v.UnaryOp.op != USub) {
         414                 :          0 :         return 0;
         415                 :            :     }
         416                 :            :     // ... of a constant ...
         417                 :          0 :     expr_ty operand = exp->v.UnaryOp.operand;
         418         [ #  # ]:          0 :     if (operand->kind != Constant_kind) {
         419                 :          0 :         return 0;
         420                 :            :     }
         421                 :            :     // ... number
         422                 :          0 :     return ensure_literal_number(operand, allow_real, allow_imaginary);
         423                 :            : }
         424                 :            :
         425                 :            : static int
         426                 :          0 : ensure_literal_complex(expr_ty exp)
         427                 :            : {
         428                 :            :     assert(exp->kind == BinOp_kind);
         429                 :          0 :     expr_ty left = exp->v.BinOp.left;
         430                 :          0 :     expr_ty right = exp->v.BinOp.right;
         431                 :            :     // Ensure op is addition or subtraction
         432   [ #  #  #  # ]:          0 :     if (exp->v.BinOp.op != Add && exp->v.BinOp.op != Sub) {
         433                 :          0 :         return 0;
         434                 :            :     }
         435                 :            :     // Check LHS is a real number (potentially signed)
         436      [ #  #  # ]:          0 :     switch (left->kind)
         437                 :            :     {
         438                 :          0 :         case Constant_kind:
         439         [ #  # ]:          0 :             if (!ensure_literal_number(left, /*real=*/true, /*imaginary=*/false)) {
         440                 :          0 :                 return 0;
         441                 :            :             }
         442                 :          0 :             break;
         443                 :          0 :         case UnaryOp_kind:
         444         [ #  # ]:          0 :             if (!ensure_literal_negative(left, /*real=*/true, /*imaginary=*/false)) {
         445                 :          0 :                 return 0;
         446                 :            :             }
         447                 :          0 :             break;
         448                 :          0 :         default:
         449                 :          0 :             return 0;
         450                 :            :     }
         451                 :            :     // Check RHS is an imaginary number (no separate sign allowed)
         452         [ #  # ]:          0 :     switch (right->kind)
         453                 :            :     {
         454                 :          0 :         case Constant_kind:
         455         [ #  # ]:          0 :             if (!ensure_literal_number(right, /*real=*/false, /*imaginary=*/true)) {
         456                 :          0 :                 return 0;
         457                 :            :             }
         458                 :          0 :             break;
         459                 :          0 :         default:
         460                 :          0 :             return 0;
         461                 :            :     }
         462                 :          0 :     return 1;
         463                 :            : }
         464                 :            :
         465                 :            : static int
         466                 :          0 : validate_pattern_match_value(struct validator *state, expr_ty exp)
         467                 :            : {
         468         [ #  # ]:          0 :     if (!validate_expr(state, exp, Load)) {
         469                 :          0 :         return 0;
         470                 :            :     }
         471                 :            :
         472   [ #  #  #  #  :          0 :     switch (exp->kind)
                       #  # ]
         473                 :            :     {
         474                 :          0 :         case Constant_kind:
         475                 :            :             /* Ellipsis and immutable sequences are not allowed.
         476                 :            :                For True, False and None, MatchSingleton() should
         477                 :            :                be used */
         478         [ #  # ]:          0 :             if (!validate_expr(state, exp, Load)) {
         479                 :          0 :                 return 0;
         480                 :            :             }
         481                 :          0 :             PyObject *literal = exp->v.Constant.value;
         482   [ #  #  #  #  :          0 :             if (PyLong_CheckExact(literal) || PyFloat_CheckExact(literal) ||
                       #  # ]
         483   [ #  #  #  # ]:          0 :                 PyBytes_CheckExact(literal) || PyComplex_CheckExact(literal) ||
         484                 :          0 :                 PyUnicode_CheckExact(literal)) {
         485                 :          0 :                 return 1;
         486                 :            :             }
         487                 :          0 :             PyErr_SetString(PyExc_ValueError,
         488                 :            :                             "unexpected constant inside of a literal pattern");
         489                 :          0 :             return 0;
         490                 :          0 :         case Attribute_kind:
         491                 :            :             // Constants and attribute lookups are always permitted
         492                 :          0 :             return 1;
         493                 :          0 :         case UnaryOp_kind:
         494                 :            :             // Negated numbers are permitted (whether real or imaginary)
         495                 :            :             // Compiler will complain if AST folding doesn't create a constant
         496         [ #  # ]:          0 :             if (ensure_literal_negative(exp, /*real=*/true, /*imaginary=*/true)) {
         497                 :          0 :                 return 1;
         498                 :            :             }
         499                 :          0 :             break;
         500                 :          0 :         case BinOp_kind:
         501                 :            :             // Complex literals are permitted
         502                 :            :             // Compiler will complain if AST folding doesn't create a constant
         503         [ #  # ]:          0 :             if (ensure_literal_complex(exp)) {
         504                 :          0 :                 return 1;
         505                 :            :             }
         506                 :          0 :             break;
         507                 :          0 :         case JoinedStr_kind:
         508                 :            :             // Handled in the later stages
         509                 :          0 :             return 1;
         510                 :          0 :         default:
         511                 :          0 :             break;
         512                 :            :     }
         513                 :          0 :     PyErr_SetString(PyExc_ValueError,
         514                 :            :                     "patterns may only match literals and attribute lookups");
         515                 :          0 :     return 0;
         516                 :            : }
         517                 :            :
         518                 :            : static int
         519                 :          0 : validate_capture(PyObject *name)
         520                 :            : {
         521         [ #  # ]:          0 :     if (_PyUnicode_EqualToASCIIString(name, "_")) {
         522                 :          0 :         PyErr_Format(PyExc_ValueError, "can't capture name '_' in patterns");
         523                 :          0 :         return 0;
         524                 :            :     }
         525                 :          0 :     return validate_name(name);
         526                 :            : }
         527                 :            :
         528                 :            : static int
         529                 :          0 : validate_pattern(struct validator *state, pattern_ty p, int star_ok)
         530                 :            : {
         531   [ #  #  #  #  :          0 :     VALIDATE_POSITIONS(p);
              #  #  #  #  #
                 #  #  #  #
                          # ]
         532                 :          0 :     int ret = -1;
         533         [ #  # ]:          0 :     if (++state->recursion_depth > state->recursion_limit) {
         534                 :          0 :         PyErr_SetString(PyExc_RecursionError,
         535                 :            :                         "maximum recursion depth exceeded during compilation");
         536                 :          0 :         return 0;
         537                 :            :     }
         538   [ #  #  #  #  :          0 :     switch (p->kind) {
                 #  #  #  #
                          # ]
         539                 :          0 :         case MatchValue_kind:
         540                 :          0 :             ret = validate_pattern_match_value(state, p->v.MatchValue.value);
         541                 :          0 :             break;
         542                 :          0 :         case MatchSingleton_kind:
         543   [ #  #  #  # ]:          0 :             ret = p->v.MatchSingleton.value == Py_None || PyBool_Check(p->v.MatchSingleton.value);
         544         [ #  # ]:          0 :             if (!ret) {
         545                 :          0 :                 PyErr_SetString(PyExc_ValueError,
         546                 :            :                                 "MatchSingleton can only contain True, False and None");
         547                 :            :             }
         548                 :          0 :             break;
         549                 :          0 :         case MatchSequence_kind:
         550                 :          0 :             ret = validate_patterns(state, p->v.MatchSequence.patterns, /*star_ok=*/1);
         551                 :          0 :             break;
         552                 :          0 :         case MatchMapping_kind:
         553   [ #  #  #  #  :          0 :             if (asdl_seq_LEN(p->v.MatchMapping.keys) != asdl_seq_LEN(p->v.MatchMapping.patterns)) {
                       #  # ]
         554                 :          0 :                 PyErr_SetString(PyExc_ValueError,
         555                 :            :                                 "MatchMapping doesn't have the same number of keys as patterns");
         556                 :          0 :                 ret = 0;
         557                 :          0 :                 break;
         558                 :            :             }
         559                 :            :
         560   [ #  #  #  # ]:          0 :             if (p->v.MatchMapping.rest && !validate_capture(p->v.MatchMapping.rest)) {
         561                 :          0 :                 ret = 0;
         562                 :          0 :                 break;
         563                 :            :             }
         564                 :            :
         565                 :          0 :             asdl_expr_seq *keys = p->v.MatchMapping.keys;
         566   [ #  #  #  # ]:          0 :             for (Py_ssize_t i = 0; i < asdl_seq_LEN(keys); i++) {
         567                 :          0 :                 expr_ty key = asdl_seq_GET(keys, i);
         568         [ #  # ]:          0 :                 if (key->kind == Constant_kind) {
         569                 :          0 :                     PyObject *literal = key->v.Constant.value;
         570   [ #  #  #  # ]:          0 :                     if (literal == Py_None || PyBool_Check(literal)) {
         571                 :            :                         /* validate_pattern_match_value will ensure the key
         572                 :            :                            doesn't contain True, False and None but it is
         573                 :            :                            syntactically valid, so we will pass those on in
         574                 :            :                            a special case. */
         575                 :          0 :                         continue;
         576                 :            :                     }
         577                 :            :                 }
         578         [ #  # ]:          0 :                 if (!validate_pattern_match_value(state, key)) {
         579                 :          0 :                     ret = 0;
         580                 :          0 :                     break;
         581                 :            :                 }
         582                 :            :             }
         583                 :            :
         584                 :          0 :             ret = validate_patterns(state, p->v.MatchMapping.patterns, /*star_ok=*/0);
         585                 :          0 :             break;
         586                 :          0 :         case MatchClass_kind:
         587   [ #  #  #  #  :          0 :             if (asdl_seq_LEN(p->v.MatchClass.kwd_attrs) != asdl_seq_LEN(p->v.MatchClass.kwd_patterns)) {
                       #  # ]
         588                 :          0 :                 PyErr_SetString(PyExc_ValueError,
         589                 :            :                                 "MatchClass doesn't have the same number of keyword attributes as patterns");
         590                 :          0 :                 ret = 0;
         591                 :          0 :                 break;
         592                 :            :             }
         593         [ #  # ]:          0 :             if (!validate_expr(state, p->v.MatchClass.cls, Load)) {
         594                 :          0 :                 ret = 0;
         595                 :          0 :                 break;
         596                 :            :             }
         597                 :            :
         598                 :          0 :             expr_ty cls = p->v.MatchClass.cls;
         599                 :            :             while (1) {
         600         [ #  # ]:          0 :                 if (cls->kind == Name_kind) {
         601                 :          0 :                     break;
         602                 :            :                 }
         603         [ #  # ]:          0 :                 else if (cls->kind == Attribute_kind) {
         604                 :          0 :                     cls = cls->v.Attribute.value;
         605                 :          0 :                     continue;
         606                 :            :                 }
         607                 :            :                 else {
         608                 :          0 :                     PyErr_SetString(PyExc_ValueError,
         609                 :            :                                     "MatchClass cls field can only contain Name or Attribute nodes.");
         610                 :          0 :                     ret = 0;
         611                 :          0 :                     break;
         612                 :            :                 }
         613                 :            :             }
         614                 :            :
         615   [ #  #  #  # ]:          0 :             for (Py_ssize_t i = 0; i < asdl_seq_LEN(p->v.MatchClass.kwd_attrs); i++) {
         616                 :          0 :                 PyObject *identifier = asdl_seq_GET(p->v.MatchClass.kwd_attrs, i);
         617         [ #  # ]:          0 :                 if (!validate_name(identifier)) {
         618                 :          0 :                     ret = 0;
         619                 :          0 :                     break;
         620                 :            :                 }
         621                 :            :             }
         622                 :            :
         623         [ #  # ]:          0 :             if (!validate_patterns(state, p->v.MatchClass.patterns, /*star_ok=*/0)) {
         624                 :          0 :                 ret = 0;
         625                 :          0 :                 break;
         626                 :            :             }
         627                 :            :
         628                 :          0 :             ret = validate_patterns(state, p->v.MatchClass.kwd_patterns, /*star_ok=*/0);
         629                 :          0 :             break;
         630                 :          0 :         case MatchStar_kind:
         631         [ #  # ]:          0 :             if (!star_ok) {
         632                 :          0 :                 PyErr_SetString(PyExc_ValueError, "can't use MatchStar here");
         633                 :          0 :                 ret = 0;
         634                 :          0 :                 break;
         635                 :            :             }
         636   [ #  #  #  # ]:          0 :             ret = p->v.MatchStar.name == NULL || validate_capture(p->v.MatchStar.name);
         637                 :          0 :             break;
         638                 :          0 :         case MatchAs_kind:
         639   [ #  #  #  # ]:          0 :             if (p->v.MatchAs.name && !validate_capture(p->v.MatchAs.name)) {
         640                 :          0 :                 ret = 0;
         641                 :          0 :                 break;
         642                 :            :             }
         643         [ #  # ]:          0 :             if (p->v.MatchAs.pattern == NULL) {
         644                 :          0 :                 ret = 1;
         645                 :            :             }
         646         [ #  # ]:          0 :             else if (p->v.MatchAs.name == NULL) {
         647                 :          0 :                 PyErr_SetString(PyExc_ValueError,
         648                 :            :                                 "MatchAs must specify a target name if a pattern is given");
         649                 :          0 :                 ret = 0;
         650                 :            :             }
         651                 :            :             else {
         652                 :          0 :                 ret = validate_pattern(state, p->v.MatchAs.pattern, /*star_ok=*/0);
         653                 :            :             }
         654                 :          0 :             break;
         655                 :          0 :         case MatchOr_kind:
         656   [ #  #  #  # ]:          0 :             if (asdl_seq_LEN(p->v.MatchOr.patterns) < 2) {
         657                 :          0 :                 PyErr_SetString(PyExc_ValueError,
         658                 :            :                                 "MatchOr requires at least 2 patterns");
         659                 :          0 :                 ret = 0;
         660                 :          0 :                 break;
         661                 :            :             }
         662                 :          0 :             ret = validate_patterns(state, p->v.MatchOr.patterns, /*star_ok=*/0);
         663                 :          0 :             break;
         664                 :            :     // No default case, so the compiler will emit a warning if new pattern
         665                 :            :     // kinds are added without being handled here
         666                 :            :     }
         667         [ #  # ]:          0 :     if (ret < 0) {
         668                 :          0 :         PyErr_SetString(PyExc_SystemError, "unexpected pattern");
         669                 :          0 :         ret = 0;
         670                 :            :     }
         671                 :          0 :     state->recursion_depth--;
         672                 :          0 :     return ret;
         673                 :            : }
         674                 :            :
         675                 :            : static int
         676                 :          0 : _validate_nonempty_seq(asdl_seq *seq, const char *what, const char *owner)
         677                 :            : {
         678   [ #  #  #  # ]:          0 :     if (asdl_seq_LEN(seq))
         679                 :          0 :         return 1;
         680                 :          0 :     PyErr_Format(PyExc_ValueError, "empty %s on %s", what, owner);
         681                 :          0 :     return 0;
         682                 :            : }
         683                 :            : #define validate_nonempty_seq(seq, what, owner) _validate_nonempty_seq((asdl_seq*)seq, what, owner)
         684                 :            :
         685                 :            : static int
         686                 :          0 : validate_assignlist(struct validator *state, asdl_expr_seq *targets, expr_context_ty ctx)
         687                 :            : {
         688   [ #  #  #  #  :          0 :     return validate_nonempty_seq(targets, "targets", ctx == Del ? "Delete" : "Assign") &&
                       #  # ]
         689                 :          0 :         validate_exprs(state, targets, ctx, 0);
         690                 :            : }
         691                 :            :
         692                 :            : static int
         693                 :          0 : validate_body(struct validator *state, asdl_stmt_seq *body, const char *owner)
         694                 :            : {
         695   [ #  #  #  # ]:          0 :     return validate_nonempty_seq(body, "body", owner) && validate_stmts(state, body);
         696                 :            : }
         697                 :            :
         698                 :            : static int
         699                 :          0 : validate_stmt(struct validator *state, stmt_ty stmt)
         700                 :            : {
         701   [ #  #  #  #  :          0 :     VALIDATE_POSITIONS(stmt);
              #  #  #  #  #
                 #  #  #  #
                          # ]
         702                 :          0 :     int ret = -1;
         703                 :            :     Py_ssize_t i;
         704         [ #  # ]:          0 :     if (++state->recursion_depth > state->recursion_limit) {
         705                 :          0 :         PyErr_SetString(PyExc_RecursionError,
         706                 :            :                         "maximum recursion depth exceeded during compilation");
         707                 :          0 :         return 0;
         708                 :            :     }
         709   [ #  #  #  #  :          0 :     switch (stmt->kind) {
              #  #  #  #  #
              #  #  #  #  #
              #  #  #  #  #
              #  #  #  #  #
                       #  # ]
         710                 :          0 :     case FunctionDef_kind:
         711         [ #  # ]:          0 :         ret = validate_body(state, stmt->v.FunctionDef.body, "FunctionDef") &&
         712         [ #  # ]:          0 :             validate_arguments(state, stmt->v.FunctionDef.args) &&
         713         [ #  # ]:          0 :             validate_exprs(state, stmt->v.FunctionDef.decorator_list, Load, 0) &&
         714   [ #  #  #  # ]:          0 :             (!stmt->v.FunctionDef.returns ||
         715                 :          0 :              validate_expr(state, stmt->v.FunctionDef.returns, Load));
         716                 :          0 :         break;
         717                 :          0 :     case ClassDef_kind:
         718         [ #  # ]:          0 :         ret = validate_body(state, stmt->v.ClassDef.body, "ClassDef") &&
         719         [ #  # ]:          0 :             validate_exprs(state, stmt->v.ClassDef.bases, Load, 0) &&
         720   [ #  #  #  # ]:          0 :             validate_keywords(state, stmt->v.ClassDef.keywords) &&
         721                 :          0 :             validate_exprs(state, stmt->v.ClassDef.decorator_list, Load, 0);
         722                 :          0 :         break;
         723                 :          0 :     case Return_kind:
         724   [ #  #  #  # ]:          0 :         ret = !stmt->v.Return.value || validate_expr(state, stmt->v.Return.value, Load);
         725                 :          0 :         break;
         726                 :          0 :     case Delete_kind:
         727                 :          0 :         ret = validate_assignlist(state, stmt->v.Delete.targets, Del);
         728                 :          0 :         break;
         729                 :          0 :     case Assign_kind:
         730   [ #  #  #  # ]:          0 :         ret = validate_assignlist(state, stmt->v.Assign.targets, Store) &&
         731                 :          0 :             validate_expr(state, stmt->v.Assign.value, Load);
         732                 :          0 :         break;
         733                 :          0 :     case AugAssign_kind:
         734   [ #  #  #  # ]:          0 :         ret = validate_expr(state, stmt->v.AugAssign.target, Store) &&
         735                 :          0 :             validate_expr(state, stmt->v.AugAssign.value, Load);
         736                 :          0 :         break;
         737                 :          0 :     case AnnAssign_kind:
         738         [ #  # ]:          0 :         if (stmt->v.AnnAssign.target->kind != Name_kind &&
         739         [ #  # ]:          0 :             stmt->v.AnnAssign.simple) {
         740                 :          0 :             PyErr_SetString(PyExc_TypeError,
         741                 :            :                             "AnnAssign with simple non-Name target");
         742                 :          0 :             return 0;
         743                 :            :         }
         744                 :          0 :         ret = validate_expr(state, stmt->v.AnnAssign.target, Store) &&
         745   [ #  #  #  # ]:          0 :                (!stmt->v.AnnAssign.value ||
         746   [ #  #  #  # ]:          0 :                 validate_expr(state, stmt->v.AnnAssign.value, Load)) &&
         747                 :          0 :                validate_expr(state, stmt->v.AnnAssign.annotation, Load);
         748                 :          0 :         break;
         749                 :          0 :     case For_kind:
         750         [ #  # ]:          0 :         ret = validate_expr(state, stmt->v.For.target, Store) &&
         751         [ #  # ]:          0 :             validate_expr(state, stmt->v.For.iter, Load) &&
         752   [ #  #  #  # ]:          0 :             validate_body(state, stmt->v.For.body, "For") &&
         753                 :          0 :             validate_stmts(state, stmt->v.For.orelse);
         754                 :          0 :         break;
         755                 :          0 :     case AsyncFor_kind:
         756         [ #  # ]:          0 :         ret = validate_expr(state, stmt->v.AsyncFor.target, Store) &&
         757         [ #  # ]:          0 :             validate_expr(state, stmt->v.AsyncFor.iter, Load) &&
         758   [ #  #  #  # ]:          0 :             validate_body(state, stmt->v.AsyncFor.body, "AsyncFor") &&
         759                 :          0 :             validate_stmts(state, stmt->v.AsyncFor.orelse);
         760                 :          0 :         break;
         761                 :          0 :     case While_kind:
         762         [ #  # ]:          0 :         ret = validate_expr(state, stmt->v.While.test, Load) &&
         763   [ #  #  #  # ]:          0 :             validate_body(state, stmt->v.While.body, "While") &&
         764                 :          0 :             validate_stmts(state, stmt->v.While.orelse);
         765                 :          0 :         break;
         766                 :          0 :     case If_kind:
         767         [ #  # ]:          0 :         ret = validate_expr(state, stmt->v.If.test, Load) &&
         768   [ #  #  #  # ]:          0 :             validate_body(state, stmt->v.If.body, "If") &&
         769                 :          0 :             validate_stmts(state, stmt->v.If.orelse);
         770                 :          0 :         break;
         771                 :          0 :     case With_kind:
         772         [ #  # ]:          0 :         if (!validate_nonempty_seq(stmt->v.With.items, "items", "With"))
         773                 :          0 :             return 0;
         774   [ #  #  #  # ]:          0 :         for (i = 0; i < asdl_seq_LEN(stmt->v.With.items); i++) {
         775                 :          0 :             withitem_ty item = asdl_seq_GET(stmt->v.With.items, i);
         776         [ #  # ]:          0 :             if (!validate_expr(state, item->context_expr, Load) ||
         777   [ #  #  #  # ]:          0 :                 (item->optional_vars && !validate_expr(state, item->optional_vars, Store)))
         778                 :          0 :                 return 0;
         779                 :            :         }
         780                 :          0 :         ret = validate_body(state, stmt->v.With.body, "With");
         781                 :          0 :         break;
         782                 :          0 :     case AsyncWith_kind:
         783         [ #  # ]:          0 :         if (!validate_nonempty_seq(stmt->v.AsyncWith.items, "items", "AsyncWith"))
         784                 :          0 :             return 0;
         785   [ #  #  #  # ]:          0 :         for (i = 0; i < asdl_seq_LEN(stmt->v.AsyncWith.items); i++) {
         786                 :          0 :             withitem_ty item = asdl_seq_GET(stmt->v.AsyncWith.items, i);
         787         [ #  # ]:          0 :             if (!validate_expr(state, item->context_expr, Load) ||
         788   [ #  #  #  # ]:          0 :                 (item->optional_vars && !validate_expr(state, item->optional_vars, Store)))
         789                 :          0 :                 return 0;
         790                 :            :         }
         791                 :          0 :         ret = validate_body(state, stmt->v.AsyncWith.body, "AsyncWith");
         792                 :          0 :         break;
         793                 :          0 :     case Match_kind:
         794         [ #  # ]:          0 :         if (!validate_expr(state, stmt->v.Match.subject, Load)
         795         [ #  # ]:          0 :             || !validate_nonempty_seq(stmt->v.Match.cases, "cases", "Match")) {
         796                 :          0 :             return 0;
         797                 :            :         }
         798   [ #  #  #  # ]:          0 :         for (i = 0; i < asdl_seq_LEN(stmt->v.Match.cases); i++) {
         799                 :          0 :             match_case_ty m = asdl_seq_GET(stmt->v.Match.cases, i);
         800         [ #  # ]:          0 :             if (!validate_pattern(state, m->pattern, /*star_ok=*/0)
         801   [ #  #  #  # ]:          0 :                 || (m->guard && !validate_expr(state, m->guard, Load))
         802         [ #  # ]:          0 :                 || !validate_body(state, m->body, "match_case")) {
         803                 :          0 :                 return 0;
         804                 :            :             }
         805                 :            :         }
         806                 :          0 :         ret = 1;
         807                 :          0 :         break;
         808                 :          0 :     case Raise_kind:
         809         [ #  # ]:          0 :         if (stmt->v.Raise.exc) {
         810         [ #  # ]:          0 :             ret = validate_expr(state, stmt->v.Raise.exc, Load) &&
         811   [ #  #  #  # ]:          0 :                 (!stmt->v.Raise.cause || validate_expr(state, stmt->v.Raise.cause, Load));
         812                 :          0 :             break;
         813                 :            :         }
         814         [ #  # ]:          0 :         if (stmt->v.Raise.cause) {
         815                 :          0 :             PyErr_SetString(PyExc_ValueError, "Raise with cause but no exception");
         816                 :          0 :             return 0;
         817                 :            :         }
         818                 :          0 :         ret = 1;
         819                 :          0 :         break;
         820                 :          0 :     case Try_kind:
         821         [ #  # ]:          0 :         if (!validate_body(state, stmt->v.Try.body, "Try"))
         822                 :          0 :             return 0;
         823   [ #  #  #  # ]:          0 :         if (!asdl_seq_LEN(stmt->v.Try.handlers) &&
         824   [ #  #  #  # ]:          0 :             !asdl_seq_LEN(stmt->v.Try.finalbody)) {
         825                 :          0 :             PyErr_SetString(PyExc_ValueError, "Try has neither except handlers nor finalbody");
         826                 :          0 :             return 0;
         827                 :            :         }
         828   [ #  #  #  # ]:          0 :         if (!asdl_seq_LEN(stmt->v.Try.handlers) &&
         829   [ #  #  #  # ]:          0 :             asdl_seq_LEN(stmt->v.Try.orelse)) {
         830                 :          0 :             PyErr_SetString(PyExc_ValueError, "Try has orelse but no except handlers");
         831                 :          0 :             return 0;
         832                 :            :         }
         833   [ #  #  #  # ]:          0 :         for (i = 0; i < asdl_seq_LEN(stmt->v.Try.handlers); i++) {
         834                 :          0 :             excepthandler_ty handler = asdl_seq_GET(stmt->v.Try.handlers, i);
         835   [ #  #  #  #  :          0 :             VALIDATE_POSITIONS(handler);
              #  #  #  #  #
                 #  #  #  #
                          # ]
         836   [ #  #  #  # ]:          0 :             if ((handler->v.ExceptHandler.type &&
         837         [ #  # ]:          0 :                  !validate_expr(state, handler->v.ExceptHandler.type, Load)) ||
         838                 :          0 :                 !validate_body(state, handler->v.ExceptHandler.body, "ExceptHandler"))
         839                 :          0 :                 return 0;
         840                 :            :         }
         841   [ #  #  #  # ]:          0 :         ret = (!asdl_seq_LEN(stmt->v.Try.finalbody) ||
         842         [ #  # ]:          0 :                 validate_stmts(state, stmt->v.Try.finalbody)) &&
         843   [ #  #  #  #  :          0 :             (!asdl_seq_LEN(stmt->v.Try.orelse) ||
                       #  # ]
         844                 :          0 :              validate_stmts(state, stmt->v.Try.orelse));
         845                 :          0 :         break;
         846                 :          0 :     case TryStar_kind:
         847         [ #  # ]:          0 :         if (!validate_body(state, stmt->v.TryStar.body, "TryStar"))
         848                 :          0 :             return 0;
         849   [ #  #  #  # ]:          0 :         if (!asdl_seq_LEN(stmt->v.TryStar.handlers) &&
         850   [ #  #  #  # ]:          0 :             !asdl_seq_LEN(stmt->v.TryStar.finalbody)) {
         851                 :          0 :             PyErr_SetString(PyExc_ValueError, "TryStar has neither except handlers nor finalbody");
         852                 :          0 :             return 0;
         853                 :            :         }
         854   [ #  #  #  # ]:          0 :         if (!asdl_seq_LEN(stmt->v.TryStar.handlers) &&
         855   [ #  #  #  # ]:          0 :             asdl_seq_LEN(stmt->v.TryStar.orelse)) {
         856                 :          0 :             PyErr_SetString(PyExc_ValueError, "TryStar has orelse but no except handlers");
         857                 :          0 :             return 0;
         858                 :            :         }
         859   [ #  #  #  # ]:          0 :         for (i = 0; i < asdl_seq_LEN(stmt->v.TryStar.handlers); i++) {
         860                 :          0 :             excepthandler_ty handler = asdl_seq_GET(stmt->v.TryStar.handlers, i);
         861   [ #  #  #  # ]:          0 :             if ((handler->v.ExceptHandler.type &&
         862         [ #  # ]:          0 :                  !validate_expr(state, handler->v.ExceptHandler.type, Load)) ||
         863                 :          0 :                 !validate_body(state, handler->v.ExceptHandler.body, "ExceptHandler"))
         864                 :          0 :                 return 0;
         865                 :            :         }
         866   [ #  #  #  # ]:          0 :         ret = (!asdl_seq_LEN(stmt->v.TryStar.finalbody) ||
         867         [ #  # ]:          0 :                 validate_stmts(state, stmt->v.TryStar.finalbody)) &&
         868   [ #  #  #  #  :          0 :             (!asdl_seq_LEN(stmt->v.TryStar.orelse) ||
                       #  # ]
         869                 :          0 :              validate_stmts(state, stmt->v.TryStar.orelse));
         870                 :          0 :         break;
         871                 :          0 :     case Assert_kind:
         872         [ #  # ]:          0 :         ret = validate_expr(state, stmt->v.Assert.test, Load) &&
         873   [ #  #  #  # ]:          0 :             (!stmt->v.Assert.msg || validate_expr(state, stmt->v.Assert.msg, Load));
         874                 :          0 :         break;
         875                 :          0 :     case Import_kind:
         876                 :          0 :         ret = validate_nonempty_seq(stmt->v.Import.names, "names", "Import");
         877                 :          0 :         break;
         878                 :          0 :     case ImportFrom_kind:
         879         [ #  # ]:          0 :         if (stmt->v.ImportFrom.level < 0) {
         880                 :          0 :             PyErr_SetString(PyExc_ValueError, "Negative ImportFrom level");
         881                 :          0 :             return 0;
         882                 :            :         }
         883                 :          0 :         ret = validate_nonempty_seq(stmt->v.ImportFrom.names, "names", "ImportFrom");
         884                 :          0 :         break;
         885                 :          0 :     case Global_kind:
         886                 :          0 :         ret = validate_nonempty_seq(stmt->v.Global.names, "names", "Global");
         887                 :          0 :         break;
         888                 :          0 :     case Nonlocal_kind:
         889                 :          0 :         ret = validate_nonempty_seq(stmt->v.Nonlocal.names, "names", "Nonlocal");
         890                 :          0 :         break;
         891                 :          0 :     case Expr_kind:
         892                 :          0 :         ret = validate_expr(state, stmt->v.Expr.value, Load);
         893                 :          0 :         break;
         894                 :          0 :     case AsyncFunctionDef_kind:
         895         [ #  # ]:          0 :         ret = validate_body(state, stmt->v.AsyncFunctionDef.body, "AsyncFunctionDef") &&
         896         [ #  # ]:          0 :             validate_arguments(state, stmt->v.AsyncFunctionDef.args) &&
         897         [ #  # ]:          0 :             validate_exprs(state, stmt->v.AsyncFunctionDef.decorator_list, Load, 0) &&
         898   [ #  #  #  # ]:          0 :             (!stmt->v.AsyncFunctionDef.returns ||
         899                 :          0 :              validate_expr(state, stmt->v.AsyncFunctionDef.returns, Load));
         900                 :          0 :         break;
         901                 :          0 :     case Pass_kind:
         902                 :            :     case Break_kind:
         903                 :            :     case Continue_kind:
         904                 :          0 :         ret = 1;
         905                 :          0 :         break;
         906                 :            :     // No default case so compiler emits warning for unhandled cases
         907                 :            :     }
         908         [ #  # ]:          0 :     if (ret < 0) {
         909                 :          0 :         PyErr_SetString(PyExc_SystemError, "unexpected statement");
         910                 :          0 :         ret = 0;
         911                 :            :     }
         912                 :          0 :     state->recursion_depth--;
         913                 :          0 :     return ret;
         914                 :            : }
         915                 :            :
         916                 :            : static int
         917                 :          0 : validate_stmts(struct validator *state, asdl_stmt_seq *seq)
         918                 :            : {
         919                 :            :     Py_ssize_t i;
         920   [ #  #  #  # ]:          0 :     for (i = 0; i < asdl_seq_LEN(seq); i++) {
         921                 :          0 :         stmt_ty stmt = asdl_seq_GET(seq, i);
         922         [ #  # ]:          0 :         if (stmt) {
         923         [ #  # ]:          0 :             if (!validate_stmt(state, stmt))
         924                 :          0 :                 return 0;
         925                 :            :         }
         926                 :            :         else {
         927                 :          0 :             PyErr_SetString(PyExc_ValueError,
         928                 :            :                             "None disallowed in statement list");
         929                 :          0 :             return 0;
         930                 :            :         }
         931                 :            :     }
         932                 :          0 :     return 1;
         933                 :            : }
         934                 :            :
         935                 :            : static int
         936                 :          0 : validate_exprs(struct validator *state, asdl_expr_seq *exprs, expr_context_ty ctx, int null_ok)
         937                 :            : {
         938                 :            :     Py_ssize_t i;
         939   [ #  #  #  # ]:          0 :     for (i = 0; i < asdl_seq_LEN(exprs); i++) {
         940                 :          0 :         expr_ty expr = asdl_seq_GET(exprs, i);
         941         [ #  # ]:          0 :         if (expr) {
         942         [ #  # ]:          0 :             if (!validate_expr(state, expr, ctx))
         943                 :          0 :                 return 0;
         944                 :            :         }
         945         [ #  # ]:          0 :         else if (!null_ok) {
         946                 :          0 :             PyErr_SetString(PyExc_ValueError,
         947                 :            :                             "None disallowed in expression list");
         948                 :          0 :             return 0;
         949                 :            :         }
         950                 :            :
         951                 :            :     }
         952                 :          0 :     return 1;
         953                 :            : }
         954                 :            :
         955                 :            : static int
         956                 :          0 : validate_patterns(struct validator *state, asdl_pattern_seq *patterns, int star_ok)
         957                 :            : {
         958                 :            :     Py_ssize_t i;
         959   [ #  #  #  # ]:          0 :     for (i = 0; i < asdl_seq_LEN(patterns); i++) {
         960                 :          0 :         pattern_ty pattern = asdl_seq_GET(patterns, i);
         961         [ #  # ]:          0 :         if (!validate_pattern(state, pattern, star_ok)) {
         962                 :          0 :             return 0;
         963                 :            :         }
         964                 :            :     }
         965                 :          0 :     return 1;
         966                 :            : }
         967                 :            :
         968                 :            :
         969                 :            : /* See comments in symtable.c. */
         970                 :            : #define COMPILER_STACK_FRAME_SCALE 3
         971                 :            :
         972                 :            : int
         973                 :          0 : _PyAST_Validate(mod_ty mod)
         974                 :            : {
         975                 :          0 :     int res = -1;
         976                 :            :     struct validator state;
         977                 :            :     PyThreadState *tstate;
         978                 :            :     int starting_recursion_depth;
         979                 :            :
         980                 :            :     /* Setup recursion depth check counters */
         981                 :          0 :     tstate = _PyThreadState_GET();
         982         [ #  # ]:          0 :     if (!tstate) {
         983                 :          0 :         return 0;
         984                 :            :     }
         985                 :            :     /* Be careful here to prevent overflow. */
         986                 :          0 :     int recursion_depth = C_RECURSION_LIMIT - tstate->c_recursion_remaining;
         987                 :          0 :     starting_recursion_depth = recursion_depth * COMPILER_STACK_FRAME_SCALE;
         988                 :          0 :     state.recursion_depth = starting_recursion_depth;
         989                 :          0 :     state.recursion_limit = C_RECURSION_LIMIT * COMPILER_STACK_FRAME_SCALE;
         990                 :            :
         991   [ #  #  #  #  :          0 :     switch (mod->kind) {
                          # ]
         992                 :          0 :     case Module_kind:
         993                 :          0 :         res = validate_stmts(&state, mod->v.Module.body);
         994                 :          0 :         break;
         995                 :          0 :     case Interactive_kind:
         996                 :          0 :         res = validate_stmts(&state, mod->v.Interactive.body);
         997                 :          0 :         break;
         998                 :          0 :     case Expression_kind:
         999                 :          0 :         res = validate_expr(&state, mod->v.Expression.body, Load);
        1000                 :          0 :         break;
        1001                 :          0 :     case FunctionType_kind:
        1002   [ #  #  #  # ]:          0 :         res = validate_exprs(&state, mod->v.FunctionType.argtypes, Load, /*null_ok=*/0) &&
        1003                 :          0 :               validate_expr(&state, mod->v.FunctionType.returns, Load);
        1004                 :          0 :         break;
        1005                 :            :     // No default case so compiler emits warning for unhandled cases
        1006                 :            :     }
        1007                 :            :
        1008         [ #  # ]:          0 :     if (res < 0) {
        1009                 :          0 :         PyErr_SetString(PyExc_SystemError, "impossible module node");
        1010                 :          0 :         return 0;
        1011                 :            :     }
        1012                 :            :
        1013                 :            :     /* Check that the recursion depth counting balanced correctly */
        1014   [ #  #  #  # ]:          0 :     if (res && state.recursion_depth != starting_recursion_depth) {
        1015                 :          0 :         PyErr_Format(PyExc_SystemError,
        1016                 :            :             "AST validator recursion depth mismatch (before=%d, after=%d)",
        1017                 :            :             starting_recursion_depth, state.recursion_depth);
        1018                 :          0 :         return 0;
        1019                 :            :     }
        1020                 :          0 :     return res;
        1021                 :            : }
        1022                 :            :
        1023                 :            : PyObject *
        1024                 :      19124 : _PyAST_GetDocString(asdl_stmt_seq *body)
        1025                 :            : {
        1026   [ +  +  -  + ]:      19124 :     if (!asdl_seq_LEN(body)) {
        1027                 :         12 :         return NULL;
        1028                 :            :     }
        1029                 :      19112 :     stmt_ty st = asdl_seq_GET(body, 0);
        1030         [ +  + ]:      19112 :     if (st->kind != Expr_kind) {
        1031                 :      11231 :         return NULL;
        1032                 :            :     }
        1033                 :       7881 :     expr_ty e = st->v.Expr.value;
        1034   [ +  +  +  - ]:       7881 :     if (e->kind == Constant_kind && PyUnicode_CheckExact(e->v.Constant.value)) {
        1035                 :       6439 :         return e->v.Constant.value;
        1036                 :            :     }
        1037                 :       1442 :     return NULL;
        1038                 :            : }

Generated by: LCOV version 1.14