https://github.com/python/cpython/commit/efcd65cd84d5ebcc6cacb67971f235a726a205e7
commit: efcd65cd84d5ebcc6cacb67971f235a726a205e7
branch: main
author: Serhiy Storchaka <storch...@gmail.com>
committer: serhiy-storchaka <storch...@gmail.com>
date: 2024-08-03T12:45:45+03:00
summary:

gh-122313: Clean up deep recursion guarding code in the compiler (GH-122640)

Add ENTER_RECURSIVE and LEAVE_RECURSIVE macros in ast.c, ast_opt.c and
symtable.c. Remove VISIT_QUIT macro in symtable.c.

The current recursion depth counter only needs to be updated during
normal execution -- all functions should just return an error code
if an error occurs.

files:
M Python/ast.c
M Python/ast_opt.c
M Python/symtable.c

diff --git a/Python/ast.c b/Python/ast.c
index 1d1a48ec885686..bf1ff5f3ec18ba 100644
--- a/Python/ast.c
+++ b/Python/ast.c
@@ -14,6 +14,20 @@ struct validator {
     int recursion_limit;            /* recursion limit */
 };
 
+#define ENTER_RECURSIVE(ST) \
+    do { \
+        if (++(ST)->recursion_depth > (ST)->recursion_limit) { \
+            PyErr_SetString(PyExc_RecursionError, \
+                "maximum recursion depth exceeded during compilation"); \
+            return 0; \
+        } \
+    } while(0)
+
+#define LEAVE_RECURSIVE(ST) \
+    do { \
+        --(ST)->recursion_depth; \
+    } while(0)
+
 static int validate_stmts(struct validator *, asdl_stmt_seq *);
 static int validate_exprs(struct validator *, asdl_expr_seq *, 
expr_context_ty, int);
 static int validate_patterns(struct validator *, asdl_pattern_seq *, int);
@@ -166,11 +180,7 @@ validate_constant(struct validator *state, PyObject *value)
         return 1;
 
     if (PyTuple_CheckExact(value) || PyFrozenSet_CheckExact(value)) {
-        if (++state->recursion_depth > state->recursion_limit) {
-            PyErr_SetString(PyExc_RecursionError,
-                            "maximum recursion depth exceeded during 
compilation");
-            return 0;
-        }
+        ENTER_RECURSIVE(state);
 
         PyObject *it = PyObject_GetIter(value);
         if (it == NULL)
@@ -195,7 +205,7 @@ validate_constant(struct validator *state, PyObject *value)
         }
 
         Py_DECREF(it);
-        --state->recursion_depth;
+        LEAVE_RECURSIVE(state);
         return 1;
     }
 
@@ -213,11 +223,7 @@ validate_expr(struct validator *state, expr_ty exp, 
expr_context_ty ctx)
     assert(!PyErr_Occurred());
     VALIDATE_POSITIONS(exp);
     int ret = -1;
-    if (++state->recursion_depth > state->recursion_limit) {
-        PyErr_SetString(PyExc_RecursionError,
-                        "maximum recursion depth exceeded during compilation");
-        return 0;
-    }
+    ENTER_RECURSIVE(state);
     int check_ctx = 1;
     expr_context_ty actual_ctx;
 
@@ -398,7 +404,7 @@ validate_expr(struct validator *state, expr_ty exp, 
expr_context_ty ctx)
         PyErr_SetString(PyExc_SystemError, "unexpected expression");
         ret = 0;
     }
-    state->recursion_depth--;
+    LEAVE_RECURSIVE(state);
     return ret;
 }
 
@@ -544,11 +550,7 @@ validate_pattern(struct validator *state, pattern_ty p, 
int star_ok)
     assert(!PyErr_Occurred());
     VALIDATE_POSITIONS(p);
     int ret = -1;
-    if (++state->recursion_depth > state->recursion_limit) {
-        PyErr_SetString(PyExc_RecursionError,
-                        "maximum recursion depth exceeded during compilation");
-        return 0;
-    }
+    ENTER_RECURSIVE(state);
     switch (p->kind) {
         case MatchValue_kind:
             ret = validate_pattern_match_value(state, p->v.MatchValue.value);
@@ -690,7 +692,7 @@ validate_pattern(struct validator *state, pattern_ty p, int 
star_ok)
         PyErr_SetString(PyExc_SystemError, "unexpected pattern");
         ret = 0;
     }
-    state->recursion_depth--;
+    LEAVE_RECURSIVE(state);
     return ret;
 }
 
@@ -725,11 +727,7 @@ validate_stmt(struct validator *state, stmt_ty stmt)
     assert(!PyErr_Occurred());
     VALIDATE_POSITIONS(stmt);
     int ret = -1;
-    if (++state->recursion_depth > state->recursion_limit) {
-        PyErr_SetString(PyExc_RecursionError,
-                        "maximum recursion depth exceeded during compilation");
-        return 0;
-    }
+    ENTER_RECURSIVE(state);
     switch (stmt->kind) {
     case FunctionDef_kind:
         ret = validate_body(state, stmt->v.FunctionDef.body, "FunctionDef") &&
@@ -946,7 +944,7 @@ validate_stmt(struct validator *state, stmt_ty stmt)
         PyErr_SetString(PyExc_SystemError, "unexpected statement");
         ret = 0;
     }
-    state->recursion_depth--;
+    LEAVE_RECURSIVE(state);
     return ret;
 }
 
diff --git a/Python/ast_opt.c b/Python/ast_opt.c
index 2e2c78b9d4d7d2..d7a26e64150e55 100644
--- a/Python/ast_opt.c
+++ b/Python/ast_opt.c
@@ -15,6 +15,19 @@ typedef struct {
     int recursion_limit;            /* recursion limit */
 } _PyASTOptimizeState;
 
+#define ENTER_RECURSIVE(ST) \
+    do { \
+        if (++(ST)->recursion_depth > (ST)->recursion_limit) { \
+            PyErr_SetString(PyExc_RecursionError, \
+                "maximum recursion depth exceeded during compilation"); \
+            return 0; \
+        } \
+    } while(0)
+
+#define LEAVE_RECURSIVE(ST) \
+    do { \
+        --(ST)->recursion_depth; \
+    } while(0)
 
 static int
 make_const(expr_ty node, PyObject *val, PyArena *arena)
@@ -708,11 +721,7 @@ astfold_mod(mod_ty node_, PyArena *ctx_, 
_PyASTOptimizeState *state)
 static int
 astfold_expr(expr_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
 {
-    if (++state->recursion_depth > state->recursion_limit) {
-        PyErr_SetString(PyExc_RecursionError,
-                        "maximum recursion depth exceeded during compilation");
-        return 0;
-    }
+    ENTER_RECURSIVE(state);
     switch (node_->kind) {
     case BoolOp_kind:
         CALL_SEQ(astfold_expr, expr, node_->v.BoolOp.values);
@@ -811,7 +820,7 @@ astfold_expr(expr_ty node_, PyArena *ctx_, 
_PyASTOptimizeState *state)
     case Name_kind:
         if (node_->v.Name.ctx == Load &&
                 _PyUnicode_EqualToASCIIString(node_->v.Name.id, "__debug__")) {
-            state->recursion_depth--;
+            LEAVE_RECURSIVE(state);
             return make_const(node_, PyBool_FromLong(!state->optimize), ctx_);
         }
         break;
@@ -824,7 +833,7 @@ astfold_expr(expr_ty node_, PyArena *ctx_, 
_PyASTOptimizeState *state)
     // No default case, so the compiler will emit a warning if new expression
     // kinds are added without being handled here
     }
-    state->recursion_depth--;
+    LEAVE_RECURSIVE(state);;
     return 1;
 }
 
@@ -871,11 +880,7 @@ astfold_arg(arg_ty node_, PyArena *ctx_, 
_PyASTOptimizeState *state)
 static int
 astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
 {
-    if (++state->recursion_depth > state->recursion_limit) {
-        PyErr_SetString(PyExc_RecursionError,
-                        "maximum recursion depth exceeded during compilation");
-        return 0;
-    }
+    ENTER_RECURSIVE(state);
     switch (node_->kind) {
     case FunctionDef_kind:
         CALL_SEQ(astfold_type_param, type_param, 
node_->v.FunctionDef.type_params);
@@ -999,7 +1004,7 @@ astfold_stmt(stmt_ty node_, PyArena *ctx_, 
_PyASTOptimizeState *state)
     // No default case, so the compiler will emit a warning if new statement
     // kinds are added without being handled here
     }
-    state->recursion_depth--;
+    LEAVE_RECURSIVE(state);
     return 1;
 }
 
@@ -1031,11 +1036,7 @@ astfold_pattern(pattern_ty node_, PyArena *ctx_, 
_PyASTOptimizeState *state)
     // Currently, this is really only used to form complex/negative numeric
     // constants in MatchValue and MatchMapping nodes
     // We still recurse into all subexpressions and subpatterns anyway
-    if (++state->recursion_depth > state->recursion_limit) {
-        PyErr_SetString(PyExc_RecursionError,
-                        "maximum recursion depth exceeded during compilation");
-        return 0;
-    }
+    ENTER_RECURSIVE(state);
     switch (node_->kind) {
         case MatchValue_kind:
             CALL(astfold_expr, expr_ty, node_->v.MatchValue.value);
@@ -1067,7 +1068,7 @@ astfold_pattern(pattern_ty node_, PyArena *ctx_, 
_PyASTOptimizeState *state)
     // No default case, so the compiler will emit a warning if new pattern
     // kinds are added without being handled here
     }
-    state->recursion_depth--;
+    LEAVE_RECURSIVE(state);
     return 1;
 }
 
diff --git a/Python/symtable.c b/Python/symtable.c
index 89a0d8a2ccec1a..ef81a0799de3aa 100644
--- a/Python/symtable.c
+++ b/Python/symtable.c
@@ -1617,17 +1617,17 @@ symtable_enter_type_param_block(struct symtable *st, 
identifier name,
    VISIT_SEQ_TAIL permits the start of an ASDL sequence to be skipped, which is
    useful if the first node in the sequence requires special treatment.
 
-   VISIT_QUIT macro returns the specified value exiting from the function but
-   first adjusts current recursion counter depth.
-*/
+   ENTER_RECURSIVE macro increments the current recursion depth counter.
+   It should be used at the beginning of the recursive function.
 
-#define VISIT_QUIT(ST, X) \
-    return --(ST)->recursion_depth,(X)
+   LEAVE_RECURSIVE macro decrements the current recursion depth counter.
+   It should be used at the end of the recursive function.
+*/
 
 #define VISIT(ST, TYPE, V) \
     do { \
         if (!symtable_visit_ ## TYPE((ST), (V))) { \
-            VISIT_QUIT((ST), 0); \
+            return 0; \
         } \
     } while(0)
 
@@ -1638,7 +1638,7 @@ symtable_enter_type_param_block(struct symtable *st, 
identifier name,
         for (i = 0; i < asdl_seq_LEN(seq); i++) { \
             TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \
             if (!symtable_visit_ ## TYPE((ST), elt)) \
-                VISIT_QUIT((ST), 0);                 \
+                return 0;                 \
         } \
     } while(0)
 
@@ -1649,7 +1649,7 @@ symtable_enter_type_param_block(struct symtable *st, 
identifier name,
         for (i = (START); i < asdl_seq_LEN(seq); i++) { \
             TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \
             if (!symtable_visit_ ## TYPE((ST), elt)) \
-                VISIT_QUIT((ST), 0);                 \
+                return 0;                 \
         } \
     } while(0)
 
@@ -1661,10 +1661,25 @@ symtable_enter_type_param_block(struct symtable *st, 
identifier name,
             TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \
             if (!elt) continue; /* can be NULL */ \
             if (!symtable_visit_ ## TYPE((ST), elt)) \
-                VISIT_QUIT((ST), 0);             \
+                return 0;             \
         } \
     } while(0)
 
+#define ENTER_RECURSIVE(ST) \
+    do { \
+        if (++(ST)->recursion_depth > (ST)->recursion_limit) { \
+            PyErr_SetString(PyExc_RecursionError, \
+                "maximum recursion depth exceeded during compilation"); \
+            return 0; \
+        } \
+    } while(0)
+
+#define LEAVE_RECURSIVE(ST) \
+    do { \
+        --(ST)->recursion_depth; \
+    } while(0)
+
+
 static int
 symtable_record_directive(struct symtable *st, identifier name, 
_Py_SourceLocation loc)
 {
@@ -1737,15 +1752,11 @@ maybe_set_ste_coroutine_for_module(struct symtable *st, 
stmt_ty s)
 static int
 symtable_visit_stmt(struct symtable *st, stmt_ty s)
 {
-    if (++st->recursion_depth > st->recursion_limit) {
-        PyErr_SetString(PyExc_RecursionError,
-                        "maximum recursion depth exceeded during compilation");
-        VISIT_QUIT(st, 0);
-    }
+    ENTER_RECURSIVE(st);
     switch (s->kind) {
     case FunctionDef_kind: {
         if (!symtable_add_def(st, s->v.FunctionDef.name, DEF_LOCAL, 
LOCATION(s)))
-            VISIT_QUIT(st, 0);
+            return 0;
         if (s->v.FunctionDef.args->defaults)
             VISIT_SEQ(st, expr, s->v.FunctionDef.args->defaults);
         if (s->v.FunctionDef.args->kw_defaults)
@@ -1761,40 +1772,40 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
                                        s->v.FunctionDef.args->kw_defaults),
                     s->kind,
                     LOCATION(s))) {
-                VISIT_QUIT(st, 0);
+                return 0;
             }
             VISIT_SEQ(st, type_param, s->v.FunctionDef.type_params);
         }
         PySTEntryObject *new_ste = ste_new(st, s->v.FunctionDef.name, 
FunctionBlock, (void *)s,
                                            LOCATION(s));
         if (!new_ste) {
-            VISIT_QUIT(st, 0);
+            return 0;
         }
 
         if (!symtable_visit_annotations(st, s, s->v.FunctionDef.args,
                                         s->v.FunctionDef.returns, new_ste)) {
             Py_DECREF(new_ste);
-            VISIT_QUIT(st, 0);
+            return 0;
         }
         if (!symtable_enter_existing_block(st, new_ste)) {
             Py_DECREF(new_ste);
-            VISIT_QUIT(st, 0);
+            return 0;
         }
         Py_DECREF(new_ste);
         VISIT(st, arguments, s->v.FunctionDef.args);
         VISIT_SEQ(st, stmt, s->v.FunctionDef.body);
         if (!symtable_exit_block(st))
-            VISIT_QUIT(st, 0);
+            return 0;
         if (asdl_seq_LEN(s->v.FunctionDef.type_params) > 0) {
             if (!symtable_exit_block(st))
-                VISIT_QUIT(st, 0);
+                return 0;
         }
         break;
     }
     case ClassDef_kind: {
         PyObject *tmp;
         if (!symtable_add_def(st, s->v.ClassDef.name, DEF_LOCAL, LOCATION(s)))
-            VISIT_QUIT(st, 0);
+            return 0;
         if (s->v.ClassDef.decorator_list)
             VISIT_SEQ(st, expr, s->v.ClassDef.decorator_list);
         tmp = st->st_private;
@@ -1803,42 +1814,42 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
                                                 (void 
*)s->v.ClassDef.type_params,
                                                 false, false, s->kind,
                                                 LOCATION(s))) {
-                VISIT_QUIT(st, 0);
+                return 0;
             }
             st->st_private = s->v.ClassDef.name;
             st->st_cur->ste_mangled_names = PySet_New(NULL);
             if (!st->st_cur->ste_mangled_names) {
-                VISIT_QUIT(st, 0);
+                return 0;
             }
             VISIT_SEQ(st, type_param, s->v.ClassDef.type_params);
         }
         VISIT_SEQ(st, expr, s->v.ClassDef.bases);
         if (!check_keywords(st, s->v.ClassDef.keywords)) {
-            VISIT_QUIT(st, 0);
+            return 0;
         }
         VISIT_SEQ(st, keyword, s->v.ClassDef.keywords);
         if (!symtable_enter_block(st, s->v.ClassDef.name, ClassBlock,
                                   (void *)s, LOCATION(s))) {
-            VISIT_QUIT(st, 0);
+            return 0;
         }
         st->st_private = s->v.ClassDef.name;
         if (asdl_seq_LEN(s->v.ClassDef.type_params) > 0) {
             if (!symtable_add_def(st, &_Py_ID(__type_params__),
                                   DEF_LOCAL, LOCATION(s))) {
-                VISIT_QUIT(st, 0);
+                return 0;
             }
             _Py_DECLARE_STR(type_params, ".type_params");
             if (!symtable_add_def(st, &_Py_STR(type_params),
                                   USE, LOCATION(s))) {
-                VISIT_QUIT(st, 0);
+                return 0;
             }
         }
         VISIT_SEQ(st, stmt, s->v.ClassDef.body);
         if (!symtable_exit_block(st))
-            VISIT_QUIT(st, 0);
+            return 0;
         if (asdl_seq_LEN(s->v.ClassDef.type_params) > 0) {
             if (!symtable_exit_block(st))
-                VISIT_QUIT(st, 0);
+                return 0;
         }
         st->st_private = tmp;
         break;
@@ -1855,24 +1866,24 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
                     (void *)s->v.TypeAlias.type_params,
                     false, false, s->kind,
                     LOCATION(s))) {
-                VISIT_QUIT(st, 0);
+                return 0;
             }
             VISIT_SEQ(st, type_param, s->v.TypeAlias.type_params);
         }
         if (!symtable_enter_block(st, name, TypeAliasBlock,
                                   (void *)s, LOCATION(s))) {
-            VISIT_QUIT(st, 0);
+            return 0;
         }
         st->st_cur->ste_can_see_class_scope = is_in_class;
         if (is_in_class && !symtable_add_def(st, &_Py_ID(__classdict__), USE, 
LOCATION(s->v.TypeAlias.value))) {
-            VISIT_QUIT(st, 0);
+            return 0;
         }
         VISIT(st, expr, s->v.TypeAlias.value);
         if (!symtable_exit_block(st))
-            VISIT_QUIT(st, 0);
+            return 0;
         if (is_generic) {
             if (!symtable_exit_block(st))
-                VISIT_QUIT(st, 0);
+                return 0;
         }
         break;
     }
@@ -1895,7 +1906,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
             expr_ty e_name = s->v.AnnAssign.target;
             long cur = symtable_lookup(st, e_name->v.Name.id);
             if (cur < 0) {
-                VISIT_QUIT(st, 0);
+                return 0;
             }
             if ((cur & (DEF_GLOBAL | DEF_NONLOCAL))
                 && (st->st_cur->ste_symbols != st->st_global)
@@ -1904,17 +1915,17 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
                              cur & DEF_GLOBAL ? GLOBAL_ANNOT : NONLOCAL_ANNOT,
                              e_name->v.Name.id);
                 SET_ERROR_LOCATION(st->st_filename, LOCATION(s));
-                VISIT_QUIT(st, 0);
+                return 0;
             }
             if (s->v.AnnAssign.simple &&
                 !symtable_add_def(st, e_name->v.Name.id,
                                   DEF_ANNOT | DEF_LOCAL, LOCATION(e_name))) {
-                VISIT_QUIT(st, 0);
+                return 0;
             }
             else {
                 if (s->v.AnnAssign.value
                     && !symtable_add_def(st, e_name->v.Name.id, DEF_LOCAL, 
LOCATION(e_name))) {
-                    VISIT_QUIT(st, 0);
+                    return 0;
                 }
             }
         }
@@ -1923,7 +1934,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
         }
         if (!symtable_visit_annotation(st, s->v.AnnAssign.annotation,
                                        (void *)((uintptr_t)st->st_cur->ste_id 
+ 1))) {
-            VISIT_QUIT(st, 0);
+            return 0;
         }
 
         if (s->v.AnnAssign.value) {
@@ -1990,7 +2001,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
     case ImportFrom_kind:
         VISIT_SEQ(st, alias, s->v.ImportFrom.names);
         if (!check_import_from(st, s)) {
-            VISIT_QUIT(st, 0);
+            return 0;
         }
         break;
     case Global_kind: {
@@ -2000,7 +2011,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
             identifier name = (identifier)asdl_seq_GET(seq, i);
             long cur = symtable_lookup(st, name);
             if (cur < 0)
-                VISIT_QUIT(st, 0);
+                return 0;
             if (cur & (DEF_PARAM | DEF_LOCAL | USE | DEF_ANNOT)) {
                 const char* msg;
                 if (cur & DEF_PARAM) {
@@ -2015,13 +2026,13 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
                 PyErr_Format(PyExc_SyntaxError,
                              msg, name);
                 SET_ERROR_LOCATION(st->st_filename, LOCATION(s));
-                VISIT_QUIT(st, 0);
+                return 0;
             }
             if (!symtable_add_def(st, name, DEF_GLOBAL, LOCATION(s))) {
-                VISIT_QUIT(st, 0);
+                return 0;
             }
             if (!symtable_record_directive(st, name, LOCATION(s))) {
-                VISIT_QUIT(st, 0);
+                return 0;
             }
         }
         break;
@@ -2033,7 +2044,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
             identifier name = (identifier)asdl_seq_GET(seq, i);
             long cur = symtable_lookup(st, name);
             if (cur < 0)
-                VISIT_QUIT(st, 0);
+                return 0;
             if (cur & (DEF_PARAM | DEF_LOCAL | USE | DEF_ANNOT)) {
                 const char* msg;
                 if (cur & DEF_PARAM) {
@@ -2047,12 +2058,12 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
                 }
                 PyErr_Format(PyExc_SyntaxError, msg, name);
                 SET_ERROR_LOCATION(st->st_filename, LOCATION(s));
-                VISIT_QUIT(st, 0);
+                return 0;
             }
             if (!symtable_add_def(st, name, DEF_NONLOCAL, LOCATION(s)))
-                VISIT_QUIT(st, 0);
+                return 0;
             if (!symtable_record_directive(st, name, LOCATION(s))) {
-                VISIT_QUIT(st, 0);
+                return 0;
             }
         }
         break;
@@ -2071,7 +2082,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
         break;
     case AsyncFunctionDef_kind: {
         if (!symtable_add_def(st, s->v.AsyncFunctionDef.name, DEF_LOCAL, 
LOCATION(s)))
-            VISIT_QUIT(st, 0);
+            return 0;
         if (s->v.AsyncFunctionDef.args->defaults)
             VISIT_SEQ(st, expr, s->v.AsyncFunctionDef.args->defaults);
         if (s->v.AsyncFunctionDef.args->kw_defaults)
@@ -2088,24 +2099,24 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
                                        
s->v.AsyncFunctionDef.args->kw_defaults),
                     s->kind,
                     LOCATION(s))) {
-                VISIT_QUIT(st, 0);
+                return 0;
             }
             VISIT_SEQ(st, type_param, s->v.AsyncFunctionDef.type_params);
         }
         PySTEntryObject *new_ste = ste_new(st, s->v.FunctionDef.name, 
FunctionBlock, (void *)s,
                                            LOCATION(s));
         if (!new_ste) {
-            VISIT_QUIT(st, 0);
+            return 0;
         }
 
         if (!symtable_visit_annotations(st, s, s->v.AsyncFunctionDef.args,
                                         s->v.AsyncFunctionDef.returns, 
new_ste)) {
             Py_DECREF(new_ste);
-            VISIT_QUIT(st, 0);
+            return 0;
         }
         if (!symtable_enter_existing_block(st, new_ste)) {
             Py_DECREF(new_ste);
-            VISIT_QUIT(st, 0);
+            return 0;
         }
         Py_DECREF(new_ste);
 
@@ -2113,17 +2124,17 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
         VISIT(st, arguments, s->v.AsyncFunctionDef.args);
         VISIT_SEQ(st, stmt, s->v.AsyncFunctionDef.body);
         if (!symtable_exit_block(st))
-            VISIT_QUIT(st, 0);
+            return 0;
         if (asdl_seq_LEN(s->v.AsyncFunctionDef.type_params) > 0) {
             if (!symtable_exit_block(st))
-                VISIT_QUIT(st, 0);
+                return 0;
         }
         break;
     }
     case AsyncWith_kind:
         maybe_set_ste_coroutine_for_module(st, s);
         if (!symtable_raise_if_not_coroutine(st, 
ASYNC_WITH_OUTSIDE_ASYNC_FUNC, LOCATION(s))) {
-            VISIT_QUIT(st, 0);
+            return 0;
         }
         VISIT_SEQ(st, withitem, s->v.AsyncWith.items);
         VISIT_SEQ(st, stmt, s->v.AsyncWith.body);
@@ -2131,7 +2142,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
     case AsyncFor_kind:
         maybe_set_ste_coroutine_for_module(st, s);
         if (!symtable_raise_if_not_coroutine(st, ASYNC_FOR_OUTSIDE_ASYNC_FUNC, 
LOCATION(s))) {
-            VISIT_QUIT(st, 0);
+            return 0;
         }
         VISIT(st, expr, s->v.AsyncFor.target);
         VISIT(st, expr, s->v.AsyncFor.iter);
@@ -2140,7 +2151,8 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
             VISIT_SEQ(st, stmt, s->v.AsyncFor.orelse);
         break;
     }
-    VISIT_QUIT(st, 1);
+    LEAVE_RECURSIVE(st);
+    return 1;
 }
 
 static int
@@ -2168,7 +2180,7 @@ symtable_extend_namedexpr_scope(struct symtable *st, 
expr_ty e)
                 (target_in_scope & DEF_LOCAL)) {
                 PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_CONFLICT, 
target_name);
                 SET_ERROR_LOCATION(st->st_filename, LOCATION(e));
-                VISIT_QUIT(st, 0);
+                return 0;
             }
             continue;
         }
@@ -2178,14 +2190,14 @@ symtable_extend_namedexpr_scope(struct symtable *st, 
expr_ty e)
             long target_in_scope = symtable_lookup_entry(st, ste, target_name);
             if (target_in_scope & DEF_GLOBAL) {
                 if (!symtable_add_def(st, target_name, DEF_GLOBAL, 
LOCATION(e)))
-                    VISIT_QUIT(st, 0);
+                    return 0;
             } else {
                 if (!symtable_add_def(st, target_name, DEF_NONLOCAL, 
LOCATION(e))) {
-                    VISIT_QUIT(st, 0);
+                    return 0;
                 }
             }
             if (!symtable_record_directive(st, target_name, LOCATION(e))) {
-                VISIT_QUIT(st, 0);
+                return 0;
             }
 
             return symtable_add_def_helper(st, target_name, DEF_LOCAL, ste, 
LOCATION(e));
@@ -2193,10 +2205,10 @@ symtable_extend_namedexpr_scope(struct symtable *st, 
expr_ty e)
         /* If we find a ModuleBlock entry, add as GLOBAL */
         if (ste->ste_type == ModuleBlock) {
             if (!symtable_add_def(st, target_name, DEF_GLOBAL, LOCATION(e))) {
-                VISIT_QUIT(st, 0);
+                return 0;
             }
             if (!symtable_record_directive(st, target_name, LOCATION(e))) {
-                VISIT_QUIT(st, 0);
+                return 0;
             }
 
             return symtable_add_def_helper(st, target_name, DEF_GLOBAL, ste, 
LOCATION(e));
@@ -2223,7 +2235,7 @@ symtable_extend_namedexpr_scope(struct symtable *st, 
expr_ty e)
                     Py_UNREACHABLE();
             }
             SET_ERROR_LOCATION(st->st_filename, LOCATION(e));
-            VISIT_QUIT(st, 0);
+            return 0;
         }
     }
 
@@ -2256,18 +2268,14 @@ symtable_handle_namedexpr(struct symtable *st, expr_ty 
e)
 static int
 symtable_visit_expr(struct symtable *st, expr_ty e)
 {
-    if (++st->recursion_depth > st->recursion_limit) {
-        PyErr_SetString(PyExc_RecursionError,
-                        "maximum recursion depth exceeded during compilation");
-        VISIT_QUIT(st, 0);
-    }
+    ENTER_RECURSIVE(st);
     switch (e->kind) {
     case NamedExpr_kind:
         if (!symtable_raise_if_annotation_block(st, "named expression", e)) {
-            VISIT_QUIT(st, 0);
+            return 0;
         }
         if(!symtable_handle_namedexpr(st, e))
-            VISIT_QUIT(st, 0);
+            return 0;
         break;
     case BoolOp_kind:
         VISIT_SEQ(st, expr, e->v.BoolOp.values);
@@ -2286,12 +2294,12 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
             VISIT_SEQ_WITH_NULL(st, expr, e->v.Lambda.args->kw_defaults);
         if (!symtable_enter_block(st, &_Py_ID(lambda),
                                   FunctionBlock, (void *)e, LOCATION(e))) {
-            VISIT_QUIT(st, 0);
+            return 0;
         }
         VISIT(st, arguments, e->v.Lambda.args);
         VISIT(st, expr, e->v.Lambda.body);
         if (!symtable_exit_block(st))
-            VISIT_QUIT(st, 0);
+            return 0;
         break;
     }
     case IfExp_kind:
@@ -2308,23 +2316,23 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
         break;
     case GeneratorExp_kind:
         if (!symtable_visit_genexp(st, e))
-            VISIT_QUIT(st, 0);
+            return 0;
         break;
     case ListComp_kind:
         if (!symtable_visit_listcomp(st, e))
-            VISIT_QUIT(st, 0);
+            return 0;
         break;
     case SetComp_kind:
         if (!symtable_visit_setcomp(st, e))
-            VISIT_QUIT(st, 0);
+            return 0;
         break;
     case DictComp_kind:
         if (!symtable_visit_dictcomp(st, e))
-            VISIT_QUIT(st, 0);
+            return 0;
         break;
     case Yield_kind:
         if (!symtable_raise_if_annotation_block(st, "yield expression", e)) {
-            VISIT_QUIT(st, 0);
+            return 0;
         }
         if (e->v.Yield.value)
             VISIT(st, expr, e->v.Yield.value);
@@ -2335,7 +2343,7 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
         break;
     case YieldFrom_kind:
         if (!symtable_raise_if_annotation_block(st, "yield expression", e)) {
-            VISIT_QUIT(st, 0);
+            return 0;
         }
         VISIT(st, expr, e->v.YieldFrom.value);
         st->st_cur->ste_generator = 1;
@@ -2345,20 +2353,20 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
         break;
     case Await_kind:
         if (!symtable_raise_if_annotation_block(st, "await expression", e)) {
-            VISIT_QUIT(st, 0);
+            return 0;
         }
         if (!allows_top_level_await(st)) {
             if (!_PyST_IsFunctionLike(st->st_cur)) {
                 PyErr_SetString(PyExc_SyntaxError,
                                 "'await' outside function");
                 SET_ERROR_LOCATION(st->st_filename, LOCATION(e));
-                VISIT_QUIT(st, 0);
+                return 0;
             }
             if (!IS_ASYNC_DEF(st) && st->st_cur->ste_comprehension == 
NoComprehension) {
                 PyErr_SetString(PyExc_SyntaxError,
                                 "'await' outside async function");
                 SET_ERROR_LOCATION(st->st_filename, LOCATION(e));
-                VISIT_QUIT(st, 0);
+                return 0;
             }
         }
         VISIT(st, expr, e->v.Await.value);
@@ -2372,7 +2380,7 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
         VISIT(st, expr, e->v.Call.func);
         VISIT_SEQ(st, expr, e->v.Call.args);
         if (!check_keywords(st, e->v.Call.keywords)) {
-            VISIT_QUIT(st, 0);
+            return 0;
         }
         VISIT_SEQ_WITH_NULL(st, keyword, e->v.Call.keywords);
         break;
@@ -2390,7 +2398,7 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
     /* The following exprs can be assignment targets. */
     case Attribute_kind:
         if (!check_name(st, e->v.Attribute.attr, LOCATION(e), 
e->v.Attribute.ctx)) {
-            VISIT_QUIT(st, 0);
+            return 0;
         }
         VISIT(st, expr, e->v.Attribute.value);
         break;
@@ -2413,14 +2421,14 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
         if (!symtable_add_def_ctx(st, e->v.Name.id,
                                   e->v.Name.ctx == Load ? USE : DEF_LOCAL,
                                   LOCATION(e), e->v.Name.ctx)) {
-            VISIT_QUIT(st, 0);
+            return 0;
         }
         /* Special-case super: it counts as a use of __class__ */
         if (e->v.Name.ctx == Load &&
             _PyST_IsFunctionLike(st->st_cur) &&
             _PyUnicode_EqualToASCIIString(e->v.Name.id, "super")) {
             if (!symtable_add_def(st, &_Py_ID(__class__), USE, LOCATION(e)))
-                VISIT_QUIT(st, 0);
+                return 0;
         }
         break;
     /* child nodes of List and Tuple will have expr_context set */
@@ -2431,7 +2439,8 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
         VISIT_SEQ(st, expr, e->v.Tuple.elts);
         break;
     }
-    VISIT_QUIT(st, 1);
+    LEAVE_RECURSIVE(st);
+    return 1;
 }
 
 static int
@@ -2447,7 +2456,7 @@ symtable_visit_type_param_bound_or_default(
 
         st->st_cur->ste_can_see_class_scope = is_in_class;
         if (is_in_class && !symtable_add_def(st, &_Py_ID(__classdict__), USE, 
LOCATION(e))) {
-            VISIT_QUIT(st, 0);
+            return 0;
         }
 
         assert(ste_scope_info != NULL);
@@ -2464,15 +2473,11 @@ symtable_visit_type_param_bound_or_default(
 static int
 symtable_visit_type_param(struct symtable *st, type_param_ty tp)
 {
-    if (++st->recursion_depth > st->recursion_limit) {
-        PyErr_SetString(PyExc_RecursionError,
-                        "maximum recursion depth exceeded during compilation");
-        VISIT_QUIT(st, 0);
-    }
+    ENTER_RECURSIVE(st);
     switch(tp->kind) {
     case TypeVar_kind:
         if (!symtable_add_def(st, tp->v.TypeVar.name, DEF_TYPE_PARAM | 
DEF_LOCAL, LOCATION(tp)))
-            VISIT_QUIT(st, 0);
+            return 0;
 
         const char *ste_scope_info = NULL;
         const expr_ty bound = tp->v.TypeVar.bound;
@@ -2488,46 +2493,43 @@ symtable_visit_type_param(struct symtable *st, 
type_param_ty tp)
         // compile.c where the scope is retrieved.
         if (!symtable_visit_type_param_bound_or_default(st, 
tp->v.TypeVar.bound, tp->v.TypeVar.name,
                                                         (void *)tp, 
ste_scope_info)) {
-            VISIT_QUIT(st, 0);
+            return 0;
         }
 
         if (!symtable_visit_type_param_bound_or_default(st, 
tp->v.TypeVar.default_value, tp->v.TypeVar.name,
                                                         (void *)((uintptr_t)tp 
+ 1), "a TypeVar default")) {
-            VISIT_QUIT(st, 0);
+            return 0;
         }
         break;
     case TypeVarTuple_kind:
         if (!symtable_add_def(st, tp->v.TypeVarTuple.name, DEF_TYPE_PARAM | 
DEF_LOCAL, LOCATION(tp))) {
-            VISIT_QUIT(st, 0);
+            return 0;
         }
 
         if (!symtable_visit_type_param_bound_or_default(st, 
tp->v.TypeVarTuple.default_value, tp->v.TypeVarTuple.name,
                                                         (void *)tp, "a 
TypeVarTuple default")) {
-            VISIT_QUIT(st, 0);
+            return 0;
         }
         break;
     case ParamSpec_kind:
         if (!symtable_add_def(st, tp->v.ParamSpec.name, DEF_TYPE_PARAM | 
DEF_LOCAL, LOCATION(tp))) {
-            VISIT_QUIT(st, 0);
+            return 0;
         }
 
         if (!symtable_visit_type_param_bound_or_default(st, 
tp->v.ParamSpec.default_value, tp->v.ParamSpec.name,
                                                         (void *)tp, "a 
ParamSpec default")) {
-            VISIT_QUIT(st, 0);
+            return 0;
         }
         break;
     }
-    VISIT_QUIT(st, 1);
+    LEAVE_RECURSIVE(st);
+    return 1;
 }
 
 static int
 symtable_visit_pattern(struct symtable *st, pattern_ty p)
 {
-    if (++st->recursion_depth > st->recursion_limit) {
-        PyErr_SetString(PyExc_RecursionError,
-                        "maximum recursion depth exceeded during compilation");
-        VISIT_QUIT(st, 0);
-    }
+    ENTER_RECURSIVE(st);
     switch (p->kind) {
     case MatchValue_kind:
         VISIT(st, expr, p->v.MatchValue.value);
@@ -2541,7 +2543,7 @@ symtable_visit_pattern(struct symtable *st, pattern_ty p)
     case MatchStar_kind:
         if (p->v.MatchStar.name) {
             if (!symtable_add_def(st, p->v.MatchStar.name, DEF_LOCAL, 
LOCATION(p))) {
-                VISIT_QUIT(st, 0);
+                return 0;
             }
         }
         break;
@@ -2550,7 +2552,7 @@ symtable_visit_pattern(struct symtable *st, pattern_ty p)
         VISIT_SEQ(st, pattern, p->v.MatchMapping.patterns);
         if (p->v.MatchMapping.rest) {
             if (!symtable_add_def(st, p->v.MatchMapping.rest, DEF_LOCAL, 
LOCATION(p))) {
-                VISIT_QUIT(st, 0);
+                return 0;
             }
         }
         break;
@@ -2558,7 +2560,7 @@ symtable_visit_pattern(struct symtable *st, pattern_ty p)
         VISIT(st, expr, p->v.MatchClass.cls);
         VISIT_SEQ(st, pattern, p->v.MatchClass.patterns);
         if (!check_kwd_patterns(st, p)) {
-            VISIT_QUIT(st, 0);
+            return 0;
         }
         VISIT_SEQ(st, pattern, p->v.MatchClass.kwd_patterns);
         break;
@@ -2568,7 +2570,7 @@ symtable_visit_pattern(struct symtable *st, pattern_ty p)
         }
         if (p->v.MatchAs.name) {
             if (!symtable_add_def(st, p->v.MatchAs.name, DEF_LOCAL, 
LOCATION(p))) {
-                VISIT_QUIT(st, 0);
+                return 0;
             }
         }
         break;
@@ -2576,7 +2578,8 @@ symtable_visit_pattern(struct symtable *st, pattern_ty p)
         VISIT_SEQ(st, pattern, p->v.MatchOr.patterns);
         break;
     }
-    VISIT_QUIT(st, 1);
+    LEAVE_RECURSIVE(st);
+    return 1;
 }
 
 static int
@@ -2618,7 +2621,7 @@ symtable_visit_annotation(struct symtable *st, expr_ty 
annotation, void *key)
         _Py_block_ty current_type = parent_ste->ste_type;
         if (!symtable_enter_block(st, &_Py_ID(__annotate__), AnnotationBlock,
                                     key, LOCATION(annotation))) {
-            VISIT_QUIT(st, 0);
+            return 0;
         }
         parent_ste->ste_annotation_block =
             (struct _symtable_entry *)Py_NewRef(st->st_cur);
@@ -2632,12 +2635,12 @@ symtable_visit_annotation(struct symtable *st, expr_ty 
annotation, void *key)
     }
     else {
         if (!symtable_enter_existing_block(st, 
parent_ste->ste_annotation_block)) {
-            VISIT_QUIT(st, 0);
+            return 0;
         }
     }
     VISIT(st, expr, annotation);
     if (!symtable_exit_block(st)) {
-        VISIT_QUIT(st, 0);
+        return 0;
     }
     return 1;
 }
@@ -2669,7 +2672,7 @@ symtable_visit_annotations(struct symtable *st, stmt_ty 
o, arguments_ty a, expr_
     _Py_block_ty current_type = st->st_cur->ste_type;
     if (!symtable_enter_block(st, &_Py_ID(__annotate__), AnnotationBlock,
                               (void *)a, LOCATION(o))) {
-        VISIT_QUIT(st, 0);
+        return 0;
     }
     if (is_in_class || current_type == ClassBlock) {
         st->st_cur->ste_can_see_class_scope = 1;
@@ -2696,7 +2699,7 @@ symtable_visit_annotations(struct symtable *st, stmt_ty 
o, arguments_ty a, expr_
         VISIT(st, expr, returns);
     }
     if (!symtable_exit_block(st)) {
-        VISIT_QUIT(st, 0);
+        return 0;
     }
     return 1;
 }
@@ -2963,7 +2966,7 @@ symtable_raise_if_comprehension_block(struct symtable 
*st, expr_ty e) {
             (type == DictComprehension) ? "'yield' inside dict comprehension" :
             "'yield' inside generator expression");
     SET_ERROR_LOCATION(st->st_filename, LOCATION(e));
-    VISIT_QUIT(st, 0);
+    return 0;
 }
 
 static int

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to