fix(bindings): route every drawable wrapper through PythonObjectCache
`.parent` allocated a brand-new Python wrapper on every read, so object identity never held: `kid.parent is parent` was False, and so was `kid.parent is kid.parent`. A Frame/Grid subclass reached through .parent came back as the base type with its Python attributes gone, and `.parent` could not be used as a dict key or set member. The cache-aware converter already existed -- convertDrawableToPython in UICollection.cpp -- but was file-local, so three other paths hand-rolled their own tp_alloc switch and skipped the cache: - UIDrawable::get_parent (the filed bug) - find_in_collection (mcrfpy.find / find_all) - UIEntityCollection concat and slice __getitem__ The entity sites were the worst of them: a duplicate wrapper's tp_dealloc unconditionally clears UIEntity::pyobject, destroying the #266 subclass identity ref held by the *original* wrapper. Promote the converter to UIDrawable::pyobject_for and route all sites through it; add the matching convertEntityToPython for entities. This also gives .parent the Line/Circle/Arc/Viewport3D arms it never had (they previously fell through to None). Residual gap, deliberately not closed here: the cache holds weakrefs, so a subclass wrapper GC'd while only C++ holds the object still resurrects as the base type. Closing that needs an owner-held strong ref (the #348 pattern) and is a lifetime design decision; filed separately. Verified A/B: 17 of the new test's 22 checks fail pre-fix, all pass after. Suite 330/330. Also corrects CLAUDE.md, which documented the long-deleted RET_PY_INSTANCE macro and recommended bare tp_alloc as the "most common" pattern -- i.e. taught this exact bug. closes #369
This commit is contained in:
parent
2a29e1b0a1
commit
ce15469ffc
9 changed files with 346 additions and 324 deletions
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue