[Python-checkins] r54695 - in python/trunk: Lib/test/test_struct.py Modules/_struct.c

raymond.hettinger python-checkins at python.org
Thu Apr 5 20:00:07 CEST 2007


Author: raymond.hettinger
Date: Thu Apr 5 20:00:03 2007
New Revision: 54695
Modified:
 python/trunk/Lib/test/test_struct.py
 python/trunk/Modules/_struct.c
Log:
Bug #1563759: struct.unpack doens't support buffer protocol objects
Modified: python/trunk/Lib/test/test_struct.py
==============================================================================
--- python/trunk/Lib/test/test_struct.py	(original)
+++ python/trunk/Lib/test/test_struct.py	Thu Apr 5 20:00:03 2007
@@ -614,11 +614,19 @@
 assertRaises(struct.error, pack_into, small_buf, 0, test_string)
 assertRaises(struct.error, pack_into, small_buf, 2, test_string)
 
+def test_unpack_with_buffer():
+ # SF bug 1563759: struct.unpack doens't support buffer protocol objects
+ data1 = array.array('B', '\x12\x34\x56\x78')
+ data2 = buffer('......\x12\x34\x56\x78......', 6, 4)
+ for data in [data1, data2]:
+ value, = struct.unpack('>I', data)
+ vereq(value, 0x12345678)
 
 # Test methods to pack and unpack from buffers rather than strings.
 test_unpack_from()
 test_pack_into()
 test_pack_into_fn()
+test_unpack_with_buffer()
 
 def test_bool():
 for prefix in tuple("<>!=")+('',):
Modified: python/trunk/Modules/_struct.c
==============================================================================
--- python/trunk/Modules/_struct.c	(original)
+++ python/trunk/Modules/_struct.c	Thu Apr 5 20:00:03 2007
@@ -1534,17 +1534,35 @@
 static PyObject *
 s_unpack(PyObject *self, PyObject *inputstr)
 {
+	char *start;
+	Py_ssize_t len;
+	PyObject *args=NULL, *result;
 	PyStructObject *soself = (PyStructObject *)self;
 	assert(PyStruct_Check(self));
 	assert(soself->s_codes != NULL);
-	if (inputstr == NULL || !PyString_Check(inputstr) ||
-		PyString_GET_SIZE(inputstr) != soself->s_size) {
-		PyErr_Format(StructError,
-			"unpack requires a string argument of length %zd",
-			soself->s_size);
-		return NULL;
-	}
-	return s_unpack_internal(soself, PyString_AS_STRING(inputstr));
+	if (inputstr == NULL)
+		goto fail;
+	if (PyString_Check(inputstr) &&
+		PyString_GET_SIZE(inputstr) == soself->s_size) {
+			return s_unpack_internal(soself, PyString_AS_STRING(inputstr));
+	}
+	args = PyTuple_Pack(1, inputstr);
+	if (args == NULL)
+		return NULL;
+	if (!PyArg_ParseTuple(args, "s#:unpack", &start, &len))
+		goto fail;
+	if (soself->s_size != len)
+		goto fail;
+	result = s_unpack_internal(soself, start);
+	Py_DECREF(args);
+	return result;
+
+fail:
+	Py_XDECREF(args);
+	PyErr_Format(StructError,
+		"unpack requires a string argument of length %zd",
+		soself->s_size);
+	return NULL;
 }
 
 PyDoc_STRVAR(s_unpack_from__doc__,


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /