https://github.com/python/cpython/commit/e2d4d04afb0769c7d4d78096e4ac2a206136e0c0
commit: e2d4d04afb0769c7d4d78096e4ac2a206136e0c0
branch: 3.15
author: Miss Islington (bot) <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2026-10-10T13:59:36+03:00
summary:

[3.15] gh-156466: fix cleanup on error in codegen_function_body (GH-156511) 
(GH-156578)

(cherry picked from commit d94c4ad1b65b102d10634b43bea61d35dae7baeb)

Co-authored-by: Irit Katriel <[email protected]>

files:
M Python/codegen.c

diff --git a/Python/codegen.c b/Python/codegen.c
index b2150065ceaaeb..0e6d9d1739039d 100644
--- a/Python/codegen.c
+++ b/Python/codegen.c
@@ -1370,6 +1370,44 @@ codegen_type_params(compiler *c, asdl_type_param_seq 
*type_params)
     return SUCCESS;
 }
 
+static int
+codegen_emit_function_body(compiler *c, asdl_stmt_seq *body)
+{
+    PySTEntryObject *ste = SYMTABLE_ENTRY(c);
+    Py_ssize_t first_instr = 0;
+    if (ste->ste_has_docstring) {
+        PyObject *docstring = _PyAST_GetDocString(body);
+        assert(docstring);
+        first_instr = 1;
+        docstring = _PyCompile_CleanDoc(docstring);
+        if (docstring == NULL) {
+            return ERROR;
+        }
+        Py_ssize_t idx = _PyCompile_AddConst(c, docstring);
+        Py_DECREF(docstring);
+        RETURN_IF_ERROR(idx < 0 ? ERROR : SUCCESS);
+    }
+
+    NEW_JUMP_TARGET_LABEL(c, start);
+    USE_LABEL(c, start);
+    bool add_stopiteration_handler = ste->ste_coroutine || ste->ste_generator;
+    if (add_stopiteration_handler) {
+        /* codegen_wrap_in_stopiteration_handler will push a block, so we need 
to account for that */
+        RETURN_IF_ERROR(
+            _PyCompile_PushFBlock(c, NO_LOCATION, 
COMPILE_FBLOCK_STOP_ITERATION,
+                                  start, NO_LABEL, NULL));
+    }
+
+    for (Py_ssize_t i = first_instr; i < asdl_seq_LEN(body); i++) {
+        VISIT(c, stmt, (stmt_ty)asdl_seq_GET(body, i));
+    }
+    if (add_stopiteration_handler) {
+        RETURN_IF_ERROR(codegen_wrap_in_stopiteration_handler(c));
+        _PyCompile_PopFBlock(c, COMPILE_FBLOCK_STOP_ITERATION, start);
+    }
+    return SUCCESS;
+}
+
 static int
 codegen_function_body(compiler *c, stmt_ty s, int is_async, Py_ssize_t 
funcflags,
                       int firstlineno)
@@ -1405,39 +1443,8 @@ codegen_function_body(compiler *c, stmt_ty s, int 
is_async, Py_ssize_t funcflags
     RETURN_IF_ERROR(
         codegen_enter_scope(c, name, scope_type, (void *)s, firstlineno, NULL, 
&umd));
 
-    PySTEntryObject *ste = SYMTABLE_ENTRY(c);
-    Py_ssize_t first_instr = 0;
-    if (ste->ste_has_docstring) {
-        PyObject *docstring = _PyAST_GetDocString(body);
-        assert(docstring);
-        first_instr = 1;
-        docstring = _PyCompile_CleanDoc(docstring);
-        if (docstring == NULL) {
-            _PyCompile_ExitScope(c);
-            return ERROR;
-        }
-        Py_ssize_t idx = _PyCompile_AddConst(c, docstring);
-        Py_DECREF(docstring);
-        RETURN_IF_ERROR_IN_SCOPE(c, idx < 0 ? ERROR : SUCCESS);
-    }
+    RETURN_IF_ERROR_IN_SCOPE(c, codegen_emit_function_body(c, body));
 
-    NEW_JUMP_TARGET_LABEL(c, start);
-    USE_LABEL(c, start);
-    bool add_stopiteration_handler = ste->ste_coroutine || ste->ste_generator;
-    if (add_stopiteration_handler) {
-        /* codegen_wrap_in_stopiteration_handler will push a block, so we need 
to account for that */
-        RETURN_IF_ERROR(
-            _PyCompile_PushFBlock(c, NO_LOCATION, 
COMPILE_FBLOCK_STOP_ITERATION,
-                                  start, NO_LABEL, NULL));
-    }
-
-    for (Py_ssize_t i = first_instr; i < asdl_seq_LEN(body); i++) {
-        VISIT_IN_SCOPE(c, stmt, (stmt_ty)asdl_seq_GET(body, i));
-    }
-    if (add_stopiteration_handler) {
-        RETURN_IF_ERROR_IN_SCOPE(c, codegen_wrap_in_stopiteration_handler(c));
-        _PyCompile_PopFBlock(c, COMPILE_FBLOCK_STOP_ITERATION, start);
-    }
     PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 1);
     _PyCompile_ExitScope(c);
     if (co == NULL) {

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to