]> granicus.if.org Git - python/commitdiff
Bug #1563759: struct.unpack doens't support buffer protocol objects
authorRaymond Hettinger <python@rcn.com>
Wed, 4 Apr 2007 20:32:03 +0000 (20:32 +0000)
committerRaymond Hettinger <python@rcn.com>
Wed, 4 Apr 2007 20:32:03 +0000 (20:32 +0000)
Lib/test/test_struct.py
Misc/NEWS
Modules/_struct.c

index 66fd6672f076693b34bc666fc09779ba7aba0c06..7ecb6ac9a04dd9dde5642cef41d084c4863f41fb 100644 (file)
@@ -612,8 +612,14 @@ def test_pack_into_fn():
     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
+    data = array.array('B', '\x12\x34\x56\x78')
+    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()
index afbd326b23af0a866685e13c4e9d4876bb713927..618d5f1e085a86d4325a2f8d7afc15b797dfe762 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -134,6 +134,8 @@ Core and builtins
 Extension Modules
 -----------------
 
+- Bug #1563759: struct.unpack doens't support buffer protocol objects
+
 - Bug #1686475: Support stat'ing open files on Windows again.
 
 - Bug #1647541: Array module's buffer interface can now handle empty arrays.
index fb509872a7e60a3b56e0bf48245891d956256558..ba276b364ec942c9cb8d23fbdf42076b8a330ec5 100644 (file)
@@ -1485,17 +1485,31 @@ strings.");
 static PyObject *
 s_unpack(PyObject *self, PyObject *inputstr)
 {
+       char *start;
+       int len;
+       PyObject * args;
        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) {
+       if (inputstr != NULL && 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)) {
+               Py_DECREF(args);
+               return NULL;
+       }
+       Py_DECREF(args);
+       if (soself->s_size != len) {
                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));
+       return s_unpack_internal(soself, start);
 }
 
 PyDoc_STRVAR(s_unpack_from__doc__,