summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorAlexandre Vassalotti <alexandre@peadrop.com>2009-07-15 18:19:47 (GMT)
committerAlexandre Vassalotti <alexandre@peadrop.com>2009-07-15 18:19:47 (GMT)
commit999ecc0eaf88dc73c386d360183c3899242e7ffd (patch)
tree1d2765a5db0b26681df033728e00a14d71247480 /Modules
parentd5a23e322feb023dafa2b528210ad45faca5f78c (diff)
downloadcpython-999ecc0eaf88dc73c386d360183c3899242e7ffd.zip
cpython-999ecc0eaf88dc73c386d360183c3899242e7ffd.tar.gz
cpython-999ecc0eaf88dc73c386d360183c3899242e7ffd.tar.bz2
Issue #2389: Pickle array objects using a list representation for portability
across different machine architectures and compatibility with Python 3.x.
Diffstat (limited to 'Modules')
-rw-r--r--Modules/arraymodule.c68
1 files changed, 33 insertions, 35 deletions
diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c
index 6fad71c..018ab87 100644
--- a/Modules/arraymodule.c
+++ b/Modules/arraymodule.c
@@ -1157,40 +1157,6 @@ 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);
- }
- if (Py_SIZE(array) > 0) {
- if (array->ob_descr->itemsize
- > PY_SSIZE_T_MAX / array->ob_size) {
- return PyErr_NoMemory();
- }
- result = Py_BuildValue("O(cs#)O",
- Py_TYPE(array),
- array->ob_descr->typecode,
- array->ob_item,
- Py_SIZE(array) * array->ob_descr->itemsize,
- dict);
- } else {
- result = Py_BuildValue("O(c)O",
- Py_TYPE(array),
- array->ob_descr->typecode,
- dict);
- }
- Py_DECREF(dict);
- return result;
-}
-
-PyDoc_STRVAR(array_doc, "Return state information for pickling.");
-
-static PyObject *
array_reverse(arrayobject *self, PyObject *unused)
{
register Py_ssize_t itemsize = self->ob_descr->itemsize;
@@ -1527,6 +1493,38 @@ an array of some other type.");
#endif /* Py_USING_UNICODE */
+static PyObject *
+array_reduce(arrayobject *array)
+{
+ PyObject *dict, *result, *list;
+
+ dict = PyObject_GetAttrString((PyObject *)array, "__dict__");
+ if (dict == NULL) {
+ if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+ return NULL;
+ PyErr_Clear();
+ dict = Py_None;
+ Py_INCREF(dict);
+ }
+ /* Unlike in Python 3.x, we never use the more efficient memory
+ * representation of an array for pickling. This is unfortunately
+ * necessary to allow array objects to be unpickled by Python 3.x,
+ * since str objects from 2.x are always decoded to unicode in
+ * Python 3.x.
+ */
+ list = array_tolist(array, NULL);
+ if (list == NULL) {
+ Py_DECREF(dict);
+ return NULL;
+ }
+ result = Py_BuildValue(
+ "O(cO)O", Py_TYPE(array), array->ob_descr->typecode, list, dict);
+ Py_DECREF(list);
+ Py_DECREF(dict);
+ return result;
+}
+
+PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
static PyObject *
array_get_typecode(arrayobject *a, void *closure)
@@ -1583,7 +1581,7 @@ static PyMethodDef array_methods[] = {
{"read", (PyCFunction)array_fromfile_as_read, METH_VARARGS,
fromfile_doc},
{"__reduce__", (PyCFunction)array_reduce, METH_NOARGS,
- array_doc},
+ reduce_doc},
{"remove", (PyCFunction)array_remove, METH_O,
remove_doc},
{"reverse", (PyCFunction)array_reverse, METH_NOARGS,