Fix: Python memory leak when deferred property registration fails

Regression in [0], resolve by moving error handling
before creating new objects.

[0] a7b3047cef
This commit is contained in:
Campbell Barton
2025-09-03 21:11:55 +10:00
parent 0545fba54f
commit 90764de24d

View File

@@ -9015,14 +9015,12 @@ static int deferred_register_prop(StructRNA *srna, PyObject *key, PyObject *item
* are for sure types, save some time with error */
PyObject *py_func = static_cast<PyObject *>(((BPy_PropDeferred *)item)->fn);
PyObject *py_kw = ((BPy_PropDeferred *)item)->kw;
PyObject *py_srna_cobject, *py_ret;
/* Show the function name in errors to help give context. */
BLI_assert(PyCFunction_CheckExact(py_func));
PyMethodDef *py_func_method_def = ((PyCFunctionObject *)py_func)->m_ml;
const char *func_name = py_func_method_def->ml_name;
PyObject *args_fake;
const char *key_str = PyUnicode_AsUTF8(key);
if (*key_str == '_') {
@@ -9034,13 +9032,6 @@ static int deferred_register_prop(StructRNA *srna, PyObject *key, PyObject *item
func_name);
return -1;
}
py_srna_cobject = PyCapsule_New(srna, nullptr, nullptr);
/* Not 100% nice :/, modifies the dict passed, should be ok. */
PyDict_SetItem(py_kw, bpy_intern_str_attr, key);
args_fake = PyTuple_New(1);
PyTuple_SET_ITEM(args_fake, 0, py_srna_cobject);
PyObject *type = PyDict_GetItemString(py_kw, "type");
StructRNA *type_srna = srna_from_self(type, "");
@@ -9064,7 +9055,15 @@ static int deferred_register_prop(StructRNA *srna, PyObject *key, PyObject *item
}
}
py_ret = PyObject_Call(py_func, args_fake, py_kw);
PyObject *py_srna_cobject = PyCapsule_New(srna, nullptr, nullptr);
/* Not 100% nice :/, modifies the dict passed, should be ok. */
PyDict_SetItem(py_kw, bpy_intern_str_attr, key);
PyObject *args_fake = PyTuple_New(1);
PyTuple_SET_ITEM(args_fake, 0, py_srna_cobject);
PyObject *py_ret = PyObject_Call(py_func, args_fake, py_kw);
if (py_ret) {
Py_DECREF(py_ret);