Replace PyObject_GetAttrString with direct type references
Replace ~230 occurrences of PyObject_GetAttrString(McRFPy_API::mcrf_module, "TypeName") with direct &mcrfpydef::PyXxxType references across 32 source files. Each PyObject_GetAttrString call returns a new reference. When used inline in PyObject_IsInstance(), that reference was immediately leaked. When used for tp_alloc, the reference required careful Py_DECREF management that was often missing on error paths. Direct type references are compile-time constants that never need reference counting, eliminating ~230 potential leak sites and removing ~100 lines of Py_DECREF/Py_XDECREF cleanup code. Also adds extractDrawable() helper in UICollection.cpp to replace repeated 8-way type-check-and-extract chains with a single function call. Closes #267, closes #268 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
348826a0f5
commit
71eb01c950
32 changed files with 249 additions and 944 deletions
|
|
@ -408,9 +408,8 @@ bool UILine::hasProperty(const std::string& name) const {
|
|||
// Python API implementation
|
||||
PyObject* UILine::get_start(PyUILineObject* self, void* closure) {
|
||||
auto vec = self->data->getStart();
|
||||
auto type = (PyTypeObject*)PyObject_GetAttrString(McRFPy_API::mcrf_module, "Vector");
|
||||
auto type = &mcrfpydef::PyVectorType;
|
||||
auto obj = (PyVectorObject*)type->tp_alloc(type, 0);
|
||||
Py_DECREF(type);
|
||||
if (obj) {
|
||||
obj->data = vec;
|
||||
}
|
||||
|
|
@ -429,9 +428,8 @@ int UILine::set_start(PyUILineObject* self, PyObject* value, void* closure) {
|
|||
|
||||
PyObject* UILine::get_end(PyUILineObject* self, void* closure) {
|
||||
auto vec = self->data->getEnd();
|
||||
auto type = (PyTypeObject*)PyObject_GetAttrString(McRFPy_API::mcrf_module, "Vector");
|
||||
auto type = &mcrfpydef::PyVectorType;
|
||||
auto obj = (PyVectorObject*)type->tp_alloc(type, 0);
|
||||
Py_DECREF(type);
|
||||
if (obj) {
|
||||
obj->data = vec;
|
||||
}
|
||||
|
|
@ -450,11 +448,10 @@ int UILine::set_end(PyUILineObject* self, PyObject* value, void* closure) {
|
|||
|
||||
PyObject* UILine::get_color(PyUILineObject* self, void* closure) {
|
||||
auto color = self->data->getColor();
|
||||
auto type = (PyTypeObject*)PyObject_GetAttrString(McRFPy_API::mcrf_module, "Color");
|
||||
auto type = &mcrfpydef::PyColorType;
|
||||
PyObject* args = Py_BuildValue("(iiii)", color.r, color.g, color.b, color.a);
|
||||
PyObject* obj = PyObject_CallObject((PyObject*)type, args);
|
||||
Py_DECREF(args);
|
||||
Py_DECREF(type);
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
|
@ -660,11 +657,7 @@ int UILine::init(PyUILineObject* self, PyObject* args, PyObject* kwds) {
|
|||
}
|
||||
|
||||
// #184: Check if this is a Python subclass (for callback method support)
|
||||
PyObject* line_type = PyObject_GetAttrString(McRFPy_API::mcrf_module, "Line");
|
||||
if (line_type) {
|
||||
self->data->is_python_subclass = (PyObject*)Py_TYPE(self) != line_type;
|
||||
Py_DECREF(line_type);
|
||||
}
|
||||
self->data->is_python_subclass = (PyObject*)Py_TYPE(self) != (PyObject*)&mcrfpydef::PyUILineType;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue