GNU Info

Info Node: (python2.1-api.info)Example Cycle Collector Support

(python2.1-api.info)Example Cycle Collector Support


Prev: Supporting Cyclic Garbarge Collection Up: Supporting Cyclic Garbarge Collection
Enter node , (file) or (file)node

Example Cycle Collector Support
-------------------------------

This example shows only enough of the implementation of an extension
type to show how the garbage collector support needs to be added.  It
shows the definition of the object structure, the `tp_traverse',
`tp_clear' and `tp_dealloc' implementations, the type structure, and a
constructor -- the module initialization needed to export the
constructor to Python is not shown as there are no special
considerations there for the collector.  To make this interesting,
assume that the module exposes ways for the `container' field of the
object to be modified.  Note that since no checks are made on the type
of the object used to initialize `container', we have to assume that it
may be a container.

     #include "Python.h"
     
     typedef struct {
         PyObject_HEAD
         PyObject *container;
     } MyObject;
     
     static int
     my_traverse(MyObject *self, visitproc visit, void *arg)
     {
         if (self->container != NULL)
             return visit(self->container, arg);
         else
             return 0;
     }
     
     static int
     my_clear(MyObject *self)
     {
         Py_XDECREF(self->container);
         self->container = NULL;
     
         return 0;
     }
     
     static void
     my_dealloc(MyObject *self)
     {
         PyObject_GC_Fini((PyObject *) self);
         Py_XDECREF(self->container);
         PyObject_Del(self);
     }

     statichere PyTypeObject
     MyObject_Type = {
         PyObject_HEAD_INIT(NULL)
         0,
         "MyObject",
         sizeof(MyObject) + PyGC_HEAD_SIZE,
         0,
         (destructor)my_dealloc,     /* tp_dealloc */
         0,                          /* tp_print */
         0,                          /* tp_getattr */
         0,                          /* tp_setattr */
         0,                          /* tp_compare */
         0,                          /* tp_repr */
         0,                          /* tp_as_number */
         0,                          /* tp_as_sequence */
         0,                          /* tp_as_mapping */
         0,                          /* tp_hash */
         0,                          /* tp_call */
         0,                          /* tp_str */
         0,                          /* tp_getattro */
         0,                          /* tp_setattro */
         0,                          /* tp_as_buffer */
         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC,
         0,                          /* tp_doc */
         (traverseproc)my_traverse,  /* tp_traverse */
         (inquiry)my_clear,          /* tp_clear */
         0,                          /* tp_richcompare */
         0,                          /* tp_weaklistoffset */
     };
     
     /* This constructor should be made accessible from Python. */
     static PyObject *
     new_object(PyObject *unused, PyObject *args)
     {
         PyObject *container = NULL;
         MyObject *result = NULL;
     
         if (PyArg_ParseTuple(args, "|O:new_object", &container)) {
             result = PyObject_New(MyObject, &MyObject_Type);
             if (result != NULL) {
                 result->container = container;
                 PyObject_GC_Init();
             }
         }
         return (PyObject *) result;
     }


automatically generated by info2www version 1.2.2.9