[Python-checkins] r74014 - in python/trunk: Misc/NEWS Modules/arraymodule.c

alexandre.vassalotti python-checkins at python.org
Wed Jul 15 20:19:52 CEST 2009


Author: alexandre.vassalotti
Date: Wed Jul 15 20:19:47 2009
New Revision: 74014

Log:
Issue #2389: Pickle array objects using a list representation for portability
across different machine architectures and compatibility with Python 3.x.


Modified:
   python/trunk/Misc/NEWS
   python/trunk/Modules/arraymodule.c

Modified: python/trunk/Misc/NEWS
==============================================================================
--- python/trunk/Misc/NEWS	(original)
+++ python/trunk/Misc/NEWS	Wed Jul 15 20:19:47 2009
@@ -1262,6 +1262,8 @@
   support.EnvironmentVarGuard objects restored the environment variables
   incorrectly on __exit__.
 
+- Issue #2389: Array objects are now pickled in a portable manner.
+
 
 What's New in Python 2.6 final
 ==============================

Modified: python/trunk/Modules/arraymodule.c
==============================================================================
--- python/trunk/Modules/arraymodule.c	(original)
+++ python/trunk/Modules/arraymodule.c	Wed Jul 15 20:19:47 2009
@@ -1157,40 +1157,6 @@
 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 @@
 
 #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 @@
 	{"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,


More information about the Python-checkins mailing list