summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaymond Hettinger <python@rcn.com>2007-04-04 20:32:03 (GMT)
committerRaymond Hettinger <python@rcn.com>2007-04-04 20:32:03 (GMT)
commit3608f0570e634ac127ed9bce10d305d16a19e984 (patch)
tree9962e7dac2e1f8957cfefc47fffe22a1a47edab8
parent8863544522d78e89907bfbe18754426fdce6edea (diff)
downloadcpython-3608f0570e634ac127ed9bce10d305d16a19e984.zip
cpython-3608f0570e634ac127ed9bce10d305d16a19e984.tar.gz
cpython-3608f0570e634ac127ed9bce10d305d16a19e984.tar.bz2
Bug #1563759: struct.unpack doens't support buffer protocol objects
-rw-r--r--Lib/test/test_struct.py6
-rw-r--r--Misc/NEWS2
-rw-r--r--Modules/_struct.c20
3 files changed, 25 insertions, 3 deletions
diff --git a/Lib/test/test_struct.py b/Lib/test/test_struct.py
index 66fd667..7ecb6ac 100644
--- a/Lib/test/test_struct.py
+++ b/Lib/test/test_struct.py
@@ -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()
diff --git a/Misc/NEWS b/Misc/NEWS
index afbd326..618d5f1 100644
--- 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.
diff --git a/Modules/_struct.c b/Modules/_struct.c
index fb50987..ba276b3 100644
--- a/Modules/_struct.c
+++ b/Modules/_struct.c
@@ -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__,