Commit 0628dcfe authored by Guido van Rossum's avatar Guido van Rossum

"Fix" for SF bug #520644: __slots__ are not pickled.

As promised in my response to the bug report, I'm not really fixing
it; in fact, one could argule over what the proper fix should do.
Instead, I'm adding a little magic that raises TypeError if you try to
pickle an instance of a class that has __slots__ but doesn't define or
override __getstate__.  This is done by adding a bozo __getstate__
that always raises TypeError.
parent 06b711cb
......@@ -850,6 +850,21 @@ static PyGetSetDef subtype_getsets[] = {
{0},
};
/* bozo: __getstate__ that raises TypeError */
static PyObject *
bozo_func(PyObject *self, PyObject *args)
{
PyErr_SetString(PyExc_TypeError,
"a class that defines __slots__ without "
"defining __getstate__ cannot be pickled");
return NULL;
}
static PyMethodDef bozo_ml = {"__getstate__", bozo_func};
static PyObject *bozo_obj = NULL;
static PyObject *
type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
{
......@@ -973,6 +988,27 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
/* XXX Check against null bytes in name */
}
}
if (slots != NULL) {
/* See if *this* class defines __getstate__ */
PyObject *getstate = PyDict_GetItemString(dict,
"__getstate__");
if (getstate == NULL) {
/* If not, provide a bozo that raises TypeError */
if (bozo_obj == NULL) {
bozo_obj = PyCFunction_New(&bozo_ml, NULL);
if (bozo_obj == NULL) {
/* XXX decref various things */
return NULL;
}
}
if (PyDict_SetItemString(dict,
"__getstate__",
bozo_obj) < 0) {
/* XXX decref various things */
return NULL;
}
}
}
if (slots == NULL && base->tp_dictoffset == 0 &&
(base->tp_setattro == PyObject_GenericSetAttr ||
base->tp_setattro == NULL)) {
......@@ -1654,7 +1690,7 @@ add_methods(PyTypeObject *type, PyMethodDef *meth)
descr = PyDescr_NewMethod(type, meth);
if (descr == NULL)
return -1;
if (PyDict_SetItemString(dict,meth->ml_name,descr) < 0)
if (PyDict_SetItemString(dict,meth->ml_name, descr) < 0)
return -1;
Py_DECREF(descr);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment