Skip to content

Commit c9ee17f

Browse files
author
mwh
committed
A fix & test for
[ 496873 ] structseqs unpicklable by adding a __reduce__ method to structseqs. Will also commit this to the 2.2.1 branch momentarily. git-svn-id: http://svn.python.org/projects/python/trunk@25494 6015fed2-1504-0410-9fe1-9d1591cc4771
1 parent 54f52ce commit c9ee17f

2 files changed

Lines changed: 37 additions & 1 deletion

File tree

Lib/test/pickletester.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,13 @@ def test_metaclass(self):
248248
b = self.loads(s)
249249
self.assertEqual(a.__class__, b.__class__)
250250

251+
def test_structseq(self):
252+
import time
253+
t = time.localtime()
254+
s = self.dumps(t)
255+
u = self.loads(s)
256+
self.assertEqual(t, u)
257+
251258
class AbstractPickleModuleTests(unittest.TestCase):
252259

253260
def test_dump_closed_file(self):

Objects/structseq.c

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,27 @@ structseq_richcompare(PyObject *obj, PyObject *o2, int op)
188188
return result;
189189
}
190190

191+
static PyObject *
192+
structseq_reduce(PyStructSequence* self)
193+
{
194+
PyObject* tup;
195+
long n_fields;
196+
int i;
197+
198+
n_fields = REAL_SIZE(self);
199+
tup = PyTuple_New(n_fields);
200+
if (!tup) {
201+
return NULL;
202+
}
203+
204+
for (i = 0; i < n_fields; i++) {
205+
Py_INCREF(self->ob_item[i]);
206+
PyTuple_SET_ITEM(tup, i, self->ob_item[i]);
207+
}
208+
209+
return Py_BuildValue("(O(O))", self->ob_type, tup);
210+
}
211+
191212
static PySequenceMethods structseq_as_sequence = {
192213
(inquiry)structseq_length,
193214
(binaryfunc)structseq_concat, /* sq_concat */
@@ -199,6 +220,12 @@ static PySequenceMethods structseq_as_sequence = {
199220
(objobjproc)structseq_contains, /* sq_contains */
200221
};
201222

223+
static PyMethodDef structseq_methods[] = {
224+
{"__reduce__", (PyCFunction)structseq_reduce,
225+
METH_NOARGS, NULL},
226+
{NULL, NULL}
227+
};
228+
202229
static PyTypeObject _struct_sequence_template = {
203230
PyObject_HEAD_INIT(&PyType_Type)
204231
0, /* ob_size */
@@ -228,7 +255,7 @@ static PyTypeObject _struct_sequence_template = {
228255
0, /* tp_weaklistoffset */
229256
0, /* tp_iter */
230257
0, /* tp_iternext */
231-
0, /* tp_methods */
258+
structseq_methods, /* tp_methods */
232259
NULL, /* tp_members */
233260
0, /* tp_getset */
234261
0, /* tp_base */
@@ -282,4 +309,6 @@ PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc)
282309
PyInt_FromLong((long) desc->n_in_sequence));
283310
PyDict_SetItemString(dict, real_length_key,
284311
PyInt_FromLong((long) n_members));
312+
PyDict_SetItemString(dict, "__safe_for_unpickling__",
313+
PyInt_FromLong(1));
285314
}

0 commit comments

Comments
 (0)