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]