Issue #2389: Pickle array objects using a list representation for portability

across different machine architectures and compatibility with Python 3.x.
This commit is contained in:
Alexandre Vassalotti 2009-07-15 18:19:47 +00:00
parent d5a23e322f
commit 999ecc0eaf
2 changed files with 35 additions and 35 deletions

View file

@ -1262,6 +1262,8 @@ Tests
support.EnvironmentVarGuard objects restored the environment variables support.EnvironmentVarGuard objects restored the environment variables
incorrectly on __exit__. incorrectly on __exit__.
- Issue #2389: Array objects are now pickled in a portable manner.
What's New in Python 2.6 final What's New in Python 2.6 final
============================== ==============================

View file

@ -1156,40 +1156,6 @@ 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);
}
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 * static PyObject *
array_reverse(arrayobject *self, PyObject *unused) array_reverse(arrayobject *self, PyObject *unused)
{ {
@ -1527,6 +1493,38 @@ an array of some other type.");
#endif /* Py_USING_UNICODE */ #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 * static PyObject *
array_get_typecode(arrayobject *a, void *closure) array_get_typecode(arrayobject *a, void *closure)
@ -1583,7 +1581,7 @@ static PyMethodDef array_methods[] = {
{"read", (PyCFunction)array_fromfile_as_read, METH_VARARGS, {"read", (PyCFunction)array_fromfile_as_read, METH_VARARGS,
fromfile_doc}, fromfile_doc},
{"__reduce__", (PyCFunction)array_reduce, METH_NOARGS, {"__reduce__", (PyCFunction)array_reduce, METH_NOARGS,
array_doc}, reduce_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,