Python’s support for detecting and collecting garbage which involves circular references requires support from object types which are “containers” for other objects which may also be containers. Types which do not store references to other objects, or which only store references to atomic types (such as numbers or strings), do not need to provide any explicit support for garbage collection.
To create a container type, the tp_flags
field of the type object must
include the Py_TPFLAGS_HAVE_GC
and provide an implementation of the
tp_traverse
handler. If instances of the type are mutable, a
tp_clear
implementation must also be provided.
Py_TPFLAGS_HAVE_GC
Constructors for container types must conform to two rules:
PyObject_GC_New()
or PyObject_GC_NewVar()
.PyObject_GC_Track()
.PyObject_GC_New
(TYPE, PyTypeObject *type)PyObject_New()
but for container objects with the Py_TPFLAGS_HAVE_GC
flag set.PyObject_GC_NewVar
(TYPE, PyTypeObject *type, Py_ssize_t size)Analogous to PyObject_NewVar()
but for container objects with the
Py_TPFLAGS_HAVE_GC
flag set.
Changed in version 2.5: This function used an int
type for size. This might require
changes in your code for properly supporting 64-bit systems.
PyObject_GC_Resize
(TYPE, PyVarObject *op, Py_ssize_t newsize)Resize an object allocated by PyObject_NewVar()
. Returns the
resized object or NULL on failure. op must not be tracked by the collector yet.
Changed in version 2.5: This function used an int
type for newsize. This might
require changes in your code for properly supporting 64-bit systems.
PyObject_GC_Track
(PyObject *op)tp_traverse
handler become valid, usually near the end of the constructor._PyObject_GC_TRACK
(PyObject *op)PyObject_GC_Track()
. It should not be used for extension modules.Similarly, the deallocator for the object must conform to a similar pair of rules:
PyObject_GC_UnTrack()
must be called.PyObject_GC_Del()
.PyObject_GC_Del
(void *op)PyObject_GC_New()
or PyObject_GC_NewVar()
.PyObject_GC_UnTrack
(void *op)PyObject_GC_Track()
can be called again on this object to add it back to the set of tracked objects. The deallocator (tp_dealloc
handler) should call this for the object before any of the fields used by the tp_traverse
handler become invalid._PyObject_GC_UNTRACK
(PyObject *op)PyObject_GC_UnTrack()
. It should not be used for extension modules.The tp_traverse
handler accepts a function parameter of this type:
(*visitproc)
(PyObject *object, void *arg)tp_traverse
handler. The function should be called with an object to traverse as object and the third parameter to the tp_traverse
handler as arg. The Python core uses several visitor functions to implement cyclic garbage detection; it’s not expected that users will need to write their own visitor functions.The tp_traverse
handler must have the following type:
(*traverseproc)
(PyObject *self, visitproc visit, void *arg)To simplify writing tp_traverse
handlers, a Py_VISIT()
macro is
provided. In order to use this macro, the tp_traverse
implementation
must name its arguments exactly visit and arg:
Py_VISIT
(PyObject *o)If o is not NULL, call the visit callback, with arguments o
and arg. If visit returns a non-zero value, then return it.
Using this macro, tp_traverse
handlers
look like:
static int
my_traverse(Noddy *self, visitproc visit, void *arg)
{
Py_VISIT(self->foo);
Py_VISIT(self->bar);
return 0;
}
New in version 2.4.
The tp_clear
handler must be of the inquiry
type, or NULL
if the object is immutable.
(*inquiry)
(PyObject *self)Py_DECREF()
on a reference). The collector will call this method if it detects that this object is involved in a reference cycle.