[Zodb-checkins] CVS: Zope3/lib/python/Persistence - __init__.py:1.7 cPersistence.c:1.18
Jim Fulton
jim@zope.com
Mon, 7 Oct 2002 10:46:24 -0400
Update of /cvs-repository/Zope3/lib/python/Persistence
In directory cvs.zope.org:/tmp/cvs-serv15925/lib/python/Persistence
Modified Files:
__init__.py cPersistence.c
Log Message:
Fixed bug: Persistent objects were not picklable.
Even though they could be stored in the ZODB, there could not be
pickled because they didn't implement a working __reduce__ method.
I added a simple function, simple_new, that gets passed a type and
simply returns the result of calling it's __new__ method. I added a
__reduce__ method that uses this function. Note that this will not
work for any types with __new__ methods that require any arguments
other than the type itself.
=== Zope3/lib/python/Persistence/__init__.py 1.6 => 1.7 ===
--- Zope3/lib/python/Persistence/__init__.py:1.6 Mon Aug 5 16:08:38 2002
+++ Zope3/lib/python/Persistence/__init__.py Mon Oct 7 10:46:22 2002
@@ -15,3 +15,11 @@
from cPersistence import Persistent, BasePersistent
+# Wire up simple constructor
+import cPersistence
+simple_new = cPersistence.simple_new
+del cPersistence.simple_new
+del cPersistence
+import copy_reg
+copy_reg.constructor(simple_new)
+del copy_reg
=== Zope3/lib/python/Persistence/cPersistence.c 1.17 => 1.18 ===
--- Zope3/lib/python/Persistence/cPersistence.c:1.17 Thu Oct 3 00:16:59 2002
+++ Zope3/lib/python/Persistence/cPersistence.c Mon Oct 7 10:46:22 2002
@@ -56,6 +56,12 @@
static PyObject *s_register = NULL;
+/* Python version of the simple_new function; */
+static PyObject *py_simple_new = NULL;
+
+
+
+
PyObject *
_PyPersist_RegisterDataManager(PyPersistBaseObject *self)
{
@@ -621,6 +627,52 @@
return 0;
}
+static PyObject *
+persist_reduce(PyPersistObject *self)
+{
+ PyObject *state, *args=NULL, *result, *__getstate__;
+ PyObject *__getstate__str = NULL;
+
+ if (! __getstate__str)
+ {
+ __getstate__str = PyString_FromString("__getstate__");
+ if (! __getstate__str)
+ return NULL;
+ }
+
+ __getstate__ = PyObject_GetAttr((PyObject*)self, __getstate__str);
+ if (! __getstate__)
+ return NULL;
+
+ state = PyObject_CallObject(__getstate__, NULL);
+ Py_DECREF(__getstate__);
+ if (! state)
+ return NULL;
+
+ args = PyTuple_New(1);
+ if (! args)
+ goto err;
+
+ Py_INCREF(self->ob_type);
+ PyTuple_SET_ITEM(args, 0, (PyObject*)(self->ob_type));
+
+ result = PyTuple_New(3);
+ if (! result)
+ goto err;
+
+ Py_INCREF(py_simple_new);
+ PyTuple_SET_ITEM(result, 0, py_simple_new);
+ PyTuple_SET_ITEM(result, 1, args);
+ PyTuple_SET_ITEM(result, 2, state);
+
+ return result;
+
+ err:
+ Py_DECREF(state);
+ Py_XDECREF(args);
+ return NULL;
+}
+
static PyMethodDef base_persist_methods[] = {
{"_p_activate", (PyCFunction)_PyPersist_Load, METH_NOARGS, },
{"_p_deactivate", (PyCFunction)persist_deactivate, METH_NOARGS, },
@@ -630,6 +682,7 @@
};
static PyMethodDef persist_methods[] = {
+ {"__reduce__", (PyCFunction)persist_reduce, METH_NOARGS, },
{"__getstate__", (PyCFunction)persist_getstate, METH_NOARGS, },
{"__setstate__", persist_setstate, METH_O, },
{"_p_activate", (PyCFunction)_PyPersist_Load, METH_NOARGS, },
@@ -762,8 +815,17 @@
0, /*PyType_GenericNew,*/ /* tp_new */
};
+static PyObject *
+simple_new(PyObject *self, PyObject *type_object)
+{
+ return PyType_GenericNew((PyTypeObject*)type_object, NULL, NULL);
+}
+
static PyMethodDef PyPersist_methods[] = {
- {NULL, NULL}
+ {"simple_new", simple_new, METH_O,
+ "Create an object by simply calling a class' __new__ method without "
+ "arguments."},
+ {NULL, NULL}
};
static PyPersist_C_API_struct c_api = {
@@ -863,4 +925,8 @@
return;
if (!insenum(d, "GHOST", GHOST))
return;
+
+ py_simple_new = PyMapping_GetItemString(d, "simple_new");
+ if (! py_simple_new)
+ return;
}