SF #1085304: Make array.array pickle-able

This commit is contained in:
Raymond Hettinger 2004-12-16 16:23:40 +00:00
parent e6bdb37e5b
commit b0900e6a21
3 changed files with 46 additions and 0 deletions

View file

@ -7,6 +7,10 @@ import unittest
from test import test_support from test import test_support
from weakref import proxy from weakref import proxy
import array, cStringIO, math import array, cStringIO, math
from cPickle import loads, dumps
class ArraySubclass(array.array):
pass
tests = [] # list to accumulate all tests tests = [] # list to accumulate all tests
typecodes = "cubBhHiIlLfd" typecodes = "cubBhHiIlLfd"
@ -81,6 +85,21 @@ class BaseTest(unittest.TestCase):
self.assertNotEqual(id(a), id(b)) self.assertNotEqual(id(a), id(b))
self.assertEqual(a, b) self.assertEqual(a, b)
def test_pickle(self):
for protocol in (0, 1, 2):
a = array.array(self.typecode, self.example)
b = loads(dumps(a, protocol))
self.assertNotEqual(id(a), id(b))
self.assertEqual(a, b)
a = ArraySubclass(self.typecode, self.example)
a.x = 10
b = loads(dumps(a, protocol))
self.assertNotEqual(id(a), id(b))
self.assertEqual(a, b)
self.assertEqual(a.x, b.x)
self.assertEqual(type(a), type(b))
def test_insert(self): def test_insert(self):
a = array.array(self.typecode, self.example) a = array.array(self.typecode, self.example)
a.insert(0, self.example[0]) a.insert(0, self.example[0])

View file

@ -17,6 +17,8 @@ Core and builtins
Extension Modules Extension Modules
----------------- -----------------
- array.array objects are now picklable.
- the cPickle module no longer accepts the deprecated None option in the - the cPickle module no longer accepts the deprecated None option in the
args tuple returned by __reduce__(). args tuple returned by __reduce__().

View file

@ -1132,6 +1132,29 @@ PyDoc_STRVAR(byteswap_doc,
Byteswap all items of the array. If the items in the array are not 1, 2,\n\ Byteswap all items of the array. If the items in the array are not 1, 2,\n\
4, or 8 bytes in size, RuntimeError is raised."); 4, or 8 bytes in size, RuntimeError is raised.");
static PyObject *
array_reduce(arrayobject *array)
{
PyObject *dict, *result;
dict = PyObject_GetAttrString((PyObject *)array, "__dict__");
if (dict == NULL) {
PyErr_Clear();
dict = Py_None;
Py_INCREF(dict);
}
result = Py_BuildValue("O(cs#)O",
array->ob_type,
array->ob_descr->typecode,
array->ob_item,
array->ob_size * array->ob_descr->itemsize,
dict);
Py_DECREF(dict);
return result;
}
PyDoc_STRVAR(array_doc, "Return state information for pickling.");
static PyObject * static PyObject *
array_reverse(arrayobject *self, PyObject *unused) array_reverse(arrayobject *self, PyObject *unused)
{ {
@ -1490,6 +1513,8 @@ PyMethodDef array_methods[] = {
pop_doc}, pop_doc},
{"read", (PyCFunction)array_fromfile, METH_VARARGS, {"read", (PyCFunction)array_fromfile, METH_VARARGS,
fromfile_doc}, fromfile_doc},
{"__reduce__", (PyCFunction)array_reduce, METH_NOARGS,
array_doc},
{"remove", (PyCFunction)array_remove, METH_O, {"remove", (PyCFunction)array_remove, METH_O,
remove_doc}, remove_doc},
{"reverse", (PyCFunction)array_reverse, METH_NOARGS, {"reverse", (PyCFunction)array_reverse, METH_NOARGS,