https://github.com/python/cpython/commit/683ef4082d374eb26c1ead33f8fd989eeadc742d
commit: 683ef4082d374eb26c1ead33f8fd989eeadc742d
branch: main
author: Irit Katriel <[email protected]>
committer: iritkatriel <[email protected]>
date: 2026-08-28T21:01:47Z
summary:

gh-156466: fix cleanup on error in codegen_class_body (#156507)

files:
M Python/codegen.c

diff --git a/Python/codegen.c b/Python/codegen.c
index 17901cbc1bf976..b3e9488b0236fb 100644
--- a/Python/codegen.c
+++ b/Python/codegen.c
@@ -310,19 +310,23 @@ codegen_addop_load_const(compiler *c, location loc, 
PyObject *o)
 #define ADDOP_LOAD_CONST_IN_SCOPE(C, LOC, O) \
     RETURN_IF_ERROR_IN_SCOPE((C), codegen_addop_load_const((C), (LOC), (O)))
 
+static int
+codegen_addop_load_const_new(compiler *c, location loc, PyObject *o)
+{
+    if (o == NULL) {
+        return ERROR;
+    }
+    int ret = codegen_addop_load_const(c, loc, o);
+    Py_DECREF(o);
+    return ret;
+}
+
 /* Same as ADDOP_LOAD_CONST, but steals a reference. */
-#define ADDOP_LOAD_CONST_NEW(C, LOC, O)                                 \
-    do {                                                                \
-        PyObject *__new_const = (O);                                    \
-        if (__new_const == NULL) {                                      \
-            return ERROR;                                               \
-        }                                                               \
-        if (codegen_addop_load_const((C), (LOC), __new_const) < 0) {    \
-            Py_DECREF(__new_const);                                     \
-            return ERROR;                                               \
-        }                                                               \
-        Py_DECREF(__new_const);                                         \
-    } while (0)
+#define ADDOP_LOAD_CONST_NEW(C, LOC, O)  \
+    RETURN_IF_ERROR(codegen_addop_load_const_new((C), (LOC), (O)))
+
+#define ADDOP_LOAD_CONST_NEW_IN_SCOPE(C, LOC, O) \
+    RETURN_IF_ERROR_IN_SCOPE((C), codegen_addop_load_const_new((C), (LOC), 
(O)))
 
 static int
 codegen_addop_o(compiler *c, location loc,
@@ -1613,16 +1617,16 @@ codegen_class_body(compiler *c, stmt_ty s, int 
firstlineno)
     RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_ID(__name__), 
Load));
     /* ... and store it as __module__ */
     RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_ID(__module__), 
Store));
-    ADDOP_LOAD_CONST(c, loc, QUALNAME(c));
+    ADDOP_LOAD_CONST_IN_SCOPE(c, loc, QUALNAME(c));
     RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_ID(__qualname__), 
Store));
-    ADDOP_LOAD_CONST_NEW(c, loc, PyLong_FromLong(METADATA(c)->u_firstlineno));
+    ADDOP_LOAD_CONST_NEW_IN_SCOPE(c, loc, 
PyLong_FromLong(METADATA(c)->u_firstlineno));
     RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, 
&_Py_ID(__firstlineno__), Store));
     asdl_type_param_seq *type_params = s->v.ClassDef.type_params;
     if (asdl_seq_LEN(type_params) > 0) {
         RETURN_IF_ERROR_IN_SCOPE(c, codegen_set_type_params_in_class(c, loc));
     }
     if (SYMTABLE_ENTRY(c)->ste_needs_classdict) {
-        ADDOP(c, loc, LOAD_LOCALS);
+        ADDOP_IN_SCOPE(c, loc, LOAD_LOCALS);
 
         // We can't use codegen_nameop here because we need to generate a
         // STORE_DEREF in a class namespace, and codegen_nameop() won't do
@@ -1635,13 +1639,7 @@ codegen_class_body(compiler *c, stmt_ty s, int 
firstlineno)
     }
     /* compile the body proper */
     RETURN_IF_ERROR_IN_SCOPE(c, codegen_body(c, loc, s->v.ClassDef.body, 
false));
-    PyObject *static_attributes = _PyCompile_StaticAttributesAsTuple(c);
-    if (static_attributes == NULL) {
-        _PyCompile_ExitScope(c);
-        return ERROR;
-    }
-    ADDOP_LOAD_CONST(c, NO_LOCATION, static_attributes);
-    Py_CLEAR(static_attributes);
+    ADDOP_LOAD_CONST_NEW_IN_SCOPE(c, NO_LOCATION, 
_PyCompile_StaticAttributesAsTuple(c));
     RETURN_IF_ERROR_IN_SCOPE(
         c, codegen_nameop(c, NO_LOCATION, &_Py_ID(__static_attributes__), 
Store));
     /* The following code is artificial */
@@ -1650,7 +1648,7 @@ codegen_class_body(compiler *c, stmt_ty s, int 
firstlineno)
         /* Store __classdictcell__ into class namespace */
         int i = _PyCompile_LookupCellvar(c, &_Py_ID(__classdict__));
         RETURN_IF_ERROR_IN_SCOPE(c, i);
-        ADDOP_I(c, NO_LOCATION, LOAD_CLOSURE, i);
+        ADDOP_I_IN_SCOPE(c, NO_LOCATION, LOAD_CLOSURE, i);
         RETURN_IF_ERROR_IN_SCOPE(
             c, codegen_nameop(c, NO_LOCATION, &_Py_ID(__classdictcell__), 
Store));
     }
@@ -1659,14 +1657,14 @@ codegen_class_body(compiler *c, stmt_ty s, int 
firstlineno)
         /* Store __classcell__ into class namespace & return it */
         int i = _PyCompile_LookupCellvar(c, &_Py_ID(__class__));
         RETURN_IF_ERROR_IN_SCOPE(c, i);
-        ADDOP_I(c, NO_LOCATION, LOAD_CLOSURE, i);
-        ADDOP_I(c, NO_LOCATION, COPY, 1);
+        ADDOP_I_IN_SCOPE(c, NO_LOCATION, LOAD_CLOSURE, i);
+        ADDOP_I_IN_SCOPE(c, NO_LOCATION, COPY, 1);
         RETURN_IF_ERROR_IN_SCOPE(
             c, codegen_nameop(c, NO_LOCATION, &_Py_ID(__classcell__), Store));
     }
     else {
         /* No methods referenced __class__, so just return None */
-        ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
+        ADDOP_LOAD_CONST_IN_SCOPE(c, NO_LOCATION, Py_None);
     }
     ADDOP_IN_SCOPE(c, NO_LOCATION, RETURN_VALUE);
     /* create the code object */

_______________________________________________
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