implementing reduce protocol in C

Tom Widrick lordmacro at hotmail.com
Sat Sep 21 00:37:33 CEST 2002


"Alex Martelli"
> I recommend you use "ANSI C" style as a habit:
>
> static PyObject*
> proto_reduce(HyProtoObject* self)

That's what I get for copy/pasting from the python source code.

> Rather, you probably want to expose a factory function to be
> passed as the first item in the tuple returned by __reduce__
> (you may then want to return a 2-items tuple rather than a
> 3-items one from __reduce__, perhaps).  Just make sure said
> first item exposes an attribute named __safe_for_unpickling__
> with a true value, or register it as a "safe constructor" with
> module copy_reg.

If it's not one thing, it's another. I decided to try this route but have
been barricaded again. I stuck a _build function in the module
method table and used copy_reg in the init function to make it a
"safe constructor."

 module = PyImport_ImportModule("copy_reg");
 if(module == NULL)
  return;

 method = PyDict_GetItemString(PyModule_GetDict(module), "constructor");
 if(method == NULL)
  return;

 func = Py_FindMethod(mod_methodlist, NULL, "_build");
 if(func == NULL)
  return;

 args = PyObject_CallFunction(method, "(O)", func);
 Py_DECREF(func);
 if(args == NULL)
  return;
 else
  Py_DECREF(args);

Now cPickle is complaining that _build is not
found as __main__._build. I tried, in my python script, to directly
stick it in the namespace, but it says it's not the same.

from proto import proto
import cPickle

Root = proto('Root')
Root.spam = 'spam'
d = cPickle.dumps(Root)

cPickle.PicklingError: Can't pickle <built-in function _build>: it's not
found a
s __main__._build

and when I put
from proto import proto, _build

cPickle.PicklingError: Can't pickle <built-in function _build>: it's not the
sam
e object as __main__._build

I was easily able to do this in pure python using copy_reg, but the reason
why
I even started to port this type to C was because it was pickling/unpickling
too slowly.

I have a feeling this has something to do with wrapping the function object
from C into python.

My next attempt will be to create a factory type, like _protobuilder, that
will
be the first element of the tuple returned by __reduce__. I have the
pickling
working, now I just have to figure out how to make _protobuilder return a
proto object.

Tom







More information about the Python-list mailing list