Skip to content

Commit 467ed2c

Browse files
author
rhettinger
committed
SF #1085304: Make array.array pickle-able
git-svn-id: http://svn.python.org/projects/python/trunk@38039 6015fed2-1504-0410-9fe1-9d1591cc4771
1 parent 76ea9cc commit 467ed2c

3 files changed

Lines changed: 46 additions & 0 deletions

File tree

Lib/test/test_array.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
from test import test_support
88
from weakref import proxy
99
import array, cStringIO, math
10+
from cPickle import loads, dumps
11+
12+
class ArraySubclass(array.array):
13+
pass
1014

1115
tests = [] # list to accumulate all tests
1216
typecodes = "cubBhHiIlLfd"
@@ -81,6 +85,21 @@ def test_copy(self):
8185
self.assertNotEqual(id(a), id(b))
8286
self.assertEqual(a, b)
8387

88+
def test_pickle(self):
89+
for protocol in (0, 1, 2):
90+
a = array.array(self.typecode, self.example)
91+
b = loads(dumps(a, protocol))
92+
self.assertNotEqual(id(a), id(b))
93+
self.assertEqual(a, b)
94+
95+
a = ArraySubclass(self.typecode, self.example)
96+
a.x = 10
97+
b = loads(dumps(a, protocol))
98+
self.assertNotEqual(id(a), id(b))
99+
self.assertEqual(a, b)
100+
self.assertEqual(a.x, b.x)
101+
self.assertEqual(type(a), type(b))
102+
84103
def test_insert(self):
85104
a = array.array(self.typecode, self.example)
86105
a.insert(0, self.example[0])

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ Core and builtins
1717
Extension Modules
1818
-----------------
1919

20+
- array.array objects are now picklable.
21+
2022
- the cPickle module no longer accepts the deprecated None option in the
2123
args tuple returned by __reduce__().
2224

Modules/arraymodule.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1132,6 +1132,29 @@ PyDoc_STRVAR(byteswap_doc,
11321132
Byteswap all items of the array. If the items in the array are not 1, 2,\n\
11331133
4, or 8 bytes in size, RuntimeError is raised.");
11341134

1135+
static PyObject *
1136+
array_reduce(arrayobject *array)
1137+
{
1138+
PyObject *dict, *result;
1139+
1140+
dict = PyObject_GetAttrString((PyObject *)array, "__dict__");
1141+
if (dict == NULL) {
1142+
PyErr_Clear();
1143+
dict = Py_None;
1144+
Py_INCREF(dict);
1145+
}
1146+
result = Py_BuildValue("O(cs#)O",
1147+
array->ob_type,
1148+
array->ob_descr->typecode,
1149+
array->ob_item,
1150+
array->ob_size * array->ob_descr->itemsize,
1151+
dict);
1152+
Py_DECREF(dict);
1153+
return result;
1154+
}
1155+
1156+
PyDoc_STRVAR(array_doc, "Return state information for pickling.");
1157+
11351158
static PyObject *
11361159
array_reverse(arrayobject *self, PyObject *unused)
11371160
{
@@ -1490,6 +1513,8 @@ PyMethodDef array_methods[] = {
14901513
pop_doc},
14911514
{"read", (PyCFunction)array_fromfile, METH_VARARGS,
14921515
fromfile_doc},
1516+
{"__reduce__", (PyCFunction)array_reduce, METH_NOARGS,
1517+
array_doc},
14931518
{"remove", (PyCFunction)array_remove, METH_O,
14941519
remove_doc},
14951520
{"reverse", (PyCFunction)array_reverse, METH_NOARGS,

0 commit comments

Comments
 (0)