]> granicus.if.org Git - python/commitdiff
SF #1085304: Make array.array pickle-able
authorRaymond Hettinger <python@rcn.com>
Thu, 16 Dec 2004 16:23:40 +0000 (16:23 +0000)
committerRaymond Hettinger <python@rcn.com>
Thu, 16 Dec 2004 16:23:40 +0000 (16:23 +0000)
Lib/test/test_array.py
Misc/NEWS
Modules/arraymodule.c

index b15298fbfedc07b17540b53787d5e7ca70100185..c24b41b931a825971a0435388e479458831795aa 100755 (executable)
@@ -7,6 +7,10 @@ import unittest
 from test import test_support
 from weakref import proxy
 import array, cStringIO, math
+from cPickle import loads, dumps
+
+class ArraySubclass(array.array):
+    pass
 
 tests = [] # list to accumulate all tests
 typecodes = "cubBhHiIlLfd"
@@ -81,6 +85,21 @@ class BaseTest(unittest.TestCase):
         self.assertNotEqual(id(a), id(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):
         a = array.array(self.typecode, self.example)
         a.insert(0, self.example[0])
index 6bf7ab4dbcda4b3417f3caa6ad3f0b3d80a79524..570addacffd0ef05320100d7e7174b1a3ce2a166 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -17,6 +17,8 @@ Core and builtins
 Extension Modules
 -----------------
 
+- array.array objects are now picklable.
+
 - the cPickle module no longer accepts the deprecated None option in the
   args tuple returned by __reduce__().
 
index 7ed3b73d536ba41df6ad98be215f9cf9b943016d..64303330012cddb43a8e4ce66050f3034c2e5cac 100644 (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\
 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 *
 array_reverse(arrayobject *self, PyObject *unused)
 {
@@ -1490,6 +1513,8 @@ PyMethodDef array_methods[] = {
         pop_doc},
        {"read",        (PyCFunction)array_fromfile,    METH_VARARGS,
         fromfile_doc},
+       {"__reduce__",  (PyCFunction)array_reduce,      METH_NOARGS,
+        array_doc},
        {"remove",      (PyCFunction)array_remove,      METH_O,
         remove_doc},
        {"reverse",     (PyCFunction)array_reverse,     METH_NOARGS,