Two sections of Python 2.7's documentation mentioned adding cyclic garbage collection (CGC) support for container objects defined in extension modules.
The Python/C API Reference Manual gives two rules, i.e.,
- The memory for the object must be allocated using
PyObject_GC_New()
orPyObject_GC_NewVar()
.- Once all the fields which may contain references to other containers are initialized, it must call
PyObject_GC_Track()
.
Whereas in Extending and Embedding the Python Interpreter, for the Noddy
example, it seems that adding the Py_TPFLAGS_HAVE_GC
flag and filling tp_traverse
and tp_clear
slots would be sufficient to enable CGC support. And the two rules above are not practiced at all.
When I modified the Noddy
example to actually follow the rules of PyObject_GC_New()
/PyObject_GC_Del()
and PyObject_Track()
/PyObject_GC_UnTrack()
, it surprisingly raised assertion error saying,
Modules/gcmodule.c:348: visit_decref: Assertion "gc->gc.gc_refs != 0" failed. refcount was too small
What is the correct and safe way to implement CGC? What would be a neat example of a container object with CGC support?