[Bugfix] PyObject_GetAttrString return values leaked across 60+ call sites #267
Labels
No labels
Alpha Release Requirement
Bugfix
Demo Target
Documentation
Major Feature
Minor Feature
priority:tier1-active
priority:tier2-foundation
priority:tier3-future
priority:tier4-deferred
Refactoring & Cleanup
system:animation
system:documentation
system:grid
system:input
system:performance
system:procgen
system:python-binding
system:rendering
system:ui-hierarchy
Tiny Feature
workflow:blocked
workflow:needs-benchmark
workflow:needs-documentation
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
john/McRogueFace#267
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
PyObject_GetAttrString()returns a new reference that must bePy_DECREF'd when no longer needed. Across the codebase, 60+ call sites store the result in a local variable, use it once (typically as a type fortp_allocorPyObject_IsInstance), and never decrement the reference. Each call leaks a reference to a type object.Root Cause
The pattern appears throughout UIEntity.cpp, UIGrid.cpp, UIEntityCollection.cpp, and other files:
Affected Files (non-exhaustive)
UIEntity.cpp— ~8 calls, ~6 leakedUIGrid.cpp— ~26 calls, majority leakedUIEntityCollection.cpp— several callsImpact
Each leaked call increments the type object's refcount permanently. While type objects are singletons (so no actual memory is freed), it:
PyObject_IsInstance(value, PyObject_GetAttrString(...))pattern is particularly bad — it leaks on every property set callFix
Since these types are accessed repeatedly and are module-level singletons, the best fix is to use the
inlinePyTypeObject declarations directly instead of runtime attribute lookup:This was already done for Entity types (
&mcrfpydef::PyUIEntityType) but not consistently for Vector, Color, Texture, etc. TheinlinePyTypeObject declarations (documented in MEMORY.md) make this safe from any .cpp file.For
PyObject_IsInstancechecks:Severity
High — memory/reference leak on every property access and object creation. No crash, but contributes to memory growth and prevents clean shutdown.