diff options
author | Alexandre Vassalotti <alexandre@peadrop.com> | 2009-07-15 18:19:47 (GMT) |
---|---|---|
committer | Alexandre Vassalotti <alexandre@peadrop.com> | 2009-07-15 18:19:47 (GMT) |
commit | 999ecc0eaf88dc73c386d360183c3899242e7ffd (patch) | |
tree | 1d2765a5db0b26681df033728e00a14d71247480 /Modules | |
parent | d5a23e322feb023dafa2b528210ad45faca5f78c (diff) | |
download | cpython-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.c | 68 |
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, |