summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeorg Brandl <georg@python.org>2006-06-01 06:39:19 (GMT)
committerGeorg Brandl <georg@python.org>2006-06-01 06:39:19 (GMT)
commit85ac8508346db10592afde6c9ded8785942f60b7 (patch)
tree13c0331f8f3be4f79d13e4918c38352721db7fdf
parentb16e4e7860a7c1259bbc1776c937a019781f7f01 (diff)
downloadcpython-85ac8508346db10592afde6c9ded8785942f60b7.zip
cpython-85ac8508346db10592afde6c9ded8785942f60b7.tar.gz
cpython-85ac8508346db10592afde6c9ded8785942f60b7.tar.bz2
Correctly unpickle 2.4 exceptions via __setstate__ (patch #1498571)
-rw-r--r--Objects/exceptions.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/Objects/exceptions.c b/Objects/exceptions.c
index fbf10fe..acc7da5 100644
--- a/Objects/exceptions.c
+++ b/Objects/exceptions.c
@@ -150,6 +150,29 @@ BaseException_reduce(PyBaseExceptionObject *self)
return PyTuple_Pack(2, self->ob_type, self->args);
}
+/*
+ * Needed for backward compatibility, since exceptions used to store
+ * all their attributes in the __dict__. Code is taken from cPickle's
+ * load_build function.
+ */
+static PyObject *
+BaseException_setstate(PyObject *self, PyObject *state)
+{
+ PyObject *d_key, *d_value;
+ Py_ssize_t i = 0;
+
+ if (state != Py_None) {
+ if (!PyDict_Check(state)) {
+ PyErr_SetString(PyExc_TypeError, "state is not a dictionary");
+ return NULL;
+ }
+ while (PyDict_Next(state, &i, &d_key, &d_value)) {
+ if (PyObject_SetAttr(self, d_key, d_value) < 0)
+ return NULL;
+ }
+ }
+ Py_RETURN_NONE;
+}
#ifdef Py_USING_UNICODE
/* while this method generates fairly uninspired output, it a least
@@ -168,6 +191,7 @@ BaseException_unicode(PyBaseExceptionObject *self)
static PyMethodDef BaseException_methods[] = {
{"__reduce__", (PyCFunction)BaseException_reduce, METH_NOARGS },
+ {"__setstate__", (PyCFunction)BaseException_setstate, METH_O },
#ifdef Py_USING_UNICODE
{"__unicode__", (PyCFunction)BaseException_unicode, METH_NOARGS },
#endif