implementing reduce protocol in C

Alex Martelli aleax at aleax.it
Fri Sep 20 03:23:46 EDT 2002


Tom Widrick wrote:
        ...
> static PyObject *
> myobj_reduce(self)
> MyObject *self;
> {
> PyObject *args;
> PyObject *result;
> 
> args = PyTuple_New(5);
> if(args == NULL)
> return NULL;
> 
> PyTuple_SET_ITEM(args, 0, self->po_name);
> PyTuple_SET_ITEM(args, 1, self->po_parents);
> PyTuple_SET_ITEM(args, 2, self->po_children);
> PyTuple_SET_ITEM(args, 3, self->po_doc);
> PyTuple_SET_ITEM(args, 4, self->po_dict);

This is stealing references to the five objects you pass as items.
I'm not sure what effects this might have, but doesn't look good.
Perhaps it's a contributing factor to strange behavior (though it
would cause anomalies at pickling time, not when unpickling...).

> result = Py_BuildValue("(OOO)", self->ob_type, Py_None, args);
> return result;
> };

Looks like a leak (no decref of args) but that's not the specific
problem's that's biting you, I think.

> The type constructor wouldn't have worked as a call to unpickle the
> object so I've used basicnew instead.
> 
> static PyObject *
> myobj_basicnew()
> {
> MyObject *self;
> 
> self = PyObject_New(MyObject, &MyObject_Type);
> return (PyObject *)self;
> }

Do you expose this as the __basicnew__ static method of your type?
I'm not sure how you do so, as the definition of staticmethod
lives in funcobject.c, not exposed in the .h, I think.  Or, ditto
for classmethod.  Haven't tried exposing a __basicnew__ method
from a C-coded type, yet.  If I had to, I think I'd try to run
from C the Python-level exposed staticmethod built-in -- but since
as I said I didn't try that yet, I may be missing something.


Alex




More information about the Python-list mailing list