Merge pull request #2397 from KLayout/bugfix/issue-2396

Fixed issue #2396 (support weak refs in Python)
This commit is contained in:
Matthias Köfferlein 2026-07-20 23:03:34 +02:00 committed by GitHub
commit 7332de7260
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 25 additions and 0 deletions

View File

@ -43,6 +43,11 @@ namespace pya
void
pya_object_deallocate (PyObject *self)
{
// Clear weak refs - needed for signal binding and other purposes
#if PY_VERSION_HEX > 0x03020000
PyObject_ClearWeakRefs (self);
#endif
// This avoids an assertion in debug builds (Python, gcmodule.c - update_refs).
// In short, the GC expects not to see objects with refcount 0 and asserts.
// However, due to triggering of signals or similar, the destructor call below

View File

@ -337,6 +337,11 @@ public:
#if PY_VERSION_HEX >= 0x030D0000
// crashes with this option set
type->tp_flags &= ~Py_TPFLAGS_INLINE_VALUES;
#endif
#if PY_VERSION_HEX < 0x03000000
type->tp_flags |= Py_TPFLAGS_HAVE_WEAKREFS;
type->tp_weaklistoffset = type->tp_basicsize;
type->tp_basicsize += sizeof (PyObject *);
#endif
type->tp_basicsize += sizeof (PYAObjectBase);
type->tp_init = &pya_object_init;

View File

@ -22,6 +22,7 @@ import os
import sys
import gc
import copy
import weakref
# Set this to True to disable some tests involving exceptions
leak_check = "TEST_LEAK_CHECK" in os.environ
@ -3352,6 +3353,20 @@ class BasicTest(unittest.TestCase):
self.assertEqual(bc.str(), "xyz")
self.assertEqual(bnc.str(), "xyz")
# weak refs
def test_94(self):
b = pya.B()
b.set_str("abc")
r = weakref.ref(b)
self.assertEqual(r() is None, False)
self.assertEqual(r().str(), "abc")
b = None
self.assertEqual(r() is None, True)
# run unit tests
if __name__ == '__main__':
suite = unittest.TestSuite()