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