implementing reduce protocol in C
Tom Widrick
lordmacro at hotmail.com
Sat Sep 21 03:09:19 EDT 2002
Well, I finally got it working with a small amount of contortion. I made an
init function for pickle support, called from my module init
static void
initpickle()
{
PyObject *builtins, *globals, *build, *copy_reg, *constructor;
/* register the proto builder for cPickle */
globals = PyEval_GetGlobals();
if(globals == NULL)
return;
builtins = PyDict_GetItemString(globals, "__builtins__");
if(builtins == NULL)
return;
builtins = PyModule_GetDict(builtins);
build = Py_FindMethod(mod_methodlist, NULL, "__proto_build__");
copy_reg = PyImport_ImportModule("copy_reg");
constructor = PyDict_GetItemString(PyModule_GetDict(copy_reg),
"constructor");
PyObject_CallFunction(constructor, "(O)", build);
PyDict_SetItemString(builtins, "__proto_build__", build);
}
The trick was that I had to make a file-level variable to hold the module
object and get the
function from it in my reduce function, not Py_FindMethod(). I'm still
trying to learn about
the internal workings of Python, but it seems that the function object is
"changed" when the
module is initialized.
static PyObject *
proto_reduce(HyProtoObject *self)
{
PyObject *args;
PyObject *result;
PyObject *builder;
if(HyProtoModule == NULL || !PyModule_Check(HyProtoModule))
Py_FatalError("proto extension module not initialized properly.");
builder = PyDict_GetItemString(PyModule_GetDict(HyProtoModule),
"__proto_build__");
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("(OO)", builder, args);
Py_DECREF(args);
return result;
};
Who knows if this is "proper" but it works.
Tom
More information about the Python-list
mailing list