Commit 22872a09 authored by Raymond Hettinger's avatar Raymond Hettinger

SF #1085304: Make array.array pickle-able

parent bd8a46b8
...@@ -7,6 +7,10 @@ import unittest ...@@ -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): ...@@ -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])
......
...@@ -17,6 +17,8 @@ Core and builtins ...@@ -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__().
......
...@@ -1132,6 +1132,29 @@ PyDoc_STRVAR(byteswap_doc, ...@@ -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[] = { ...@@ -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,
......
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