implementing reduce protocol in C
Tom Widrick
lordmacro at hotmail.com
Fri Sep 20 06:14:53 EDT 2002
Alex Martelli wrote:
> 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...).
>
> Looks like a leak (no decref of args) but that's not the specific
> problem's that's biting you, I think.
>
Plain as the blank stare on my face, I'm a CPython newbie :)
static PyObject *
proto_reduce(self)
HyProtoObject *self;
{
PyObject *args;
PyObject *result;
args = PyTuple_New(5);
if(args == NULL)
return NULL;
PyTuple_SET_ITEM(args, 0, self->po_name);
Py_INCREF(self->po_name);
PyTuple_SET_ITEM(args, 1, self->po_parents);
Py_INCREF(self->po_parents);
PyTuple_SET_ITEM(args, 2, self->po_children);
Py_INCREF(self->po_children);
PyTuple_SET_ITEM(args, 3, self->po_doc);
Py_INCREF(self->po_doc);
PyTuple_SET_ITEM(args, 4, self->po_dict);
Py_INCREF(self->po_dict);
result = Py_BuildValue("(OOO)", self->ob_type, Py_None, args);
Py_DECREF(args);
return result;
};
Any better?
> 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
I have stuck it into my methodlist as follows:
static PyMethodDef proto_methodlist[] = {
{"chparents", (PyCFunction)proto_chparents, METH_VARARGS,
"change the parents of the object"},
{"__basicnew__", (PyCFunction)proto_basicnew, METH_NOARGS,
"helper for pickle"},
{"__reduce__", (PyCFunction)proto_reduce, METH_NOARGS,
"helper for pickle"},
{"__setstate__", (PyCFunction)proto_setstate, METH_VARARGS,
"helper for pickle"},
{0}
};
I see. I did not know that basicnew had to be a staticmethod on my type.
That may have something to do with the problem, and I do not know how
to make a staticmethod on a C type either. In the doc, it says no
arguments at all, and I assume the only way to do that is to have it a
staticmethod? I'll scour the source to see if I can find a way to do
that.
How was this done prior to staticmethods? Was there no support for the
basicnew way of doing it?
Thanks,
Tom
More information about the Python-list
mailing list