Skip to content

Commit 7fa1c6a

Browse files
committed
Support buffer interface for _struct.Struct.__init__
1 parent 4e60566 commit 7fa1c6a

File tree

3 files changed

+24
-6
lines changed

3 files changed

+24
-6
lines changed

Lib/test/test_struct.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ def bigendian_to_native(value):
3131
return string_reverse(value)
3232

3333
class StructTest(unittest.TestCase):
34+
def test_init(self):
35+
for cls in (bytes.decode, bytes, bytearray):
36+
s = struct.Struct(cls(b'4s'))
37+
self.assertEqual(b'1234', s.unpack_from(b'123456')[0])
38+
s.__init__(cls(b'4s'))
39+
self.assertEqual(b'1234', s.unpack_from(b'123456')[0])
40+
3441
def test_isbigendian(self):
3542
self.assertEqual((struct.pack('=i', 1)[0] == 0), ISBIGENDIAN)
3643

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Support buffer protocol for _struct.Struct.__init__ format argument

Modules/_struct.c

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1475,18 +1475,28 @@ Struct___init___impl(PyStructObject *self, PyObject *format)
14751475
if (format == NULL)
14761476
return -1;
14771477
}
1478-
/* XXX support buffer interface, too */
14791478
else {
14801479
Py_INCREF(format);
14811480
}
14821481

14831482
if (!PyBytes_Check(format)) {
1483+
int ret;
1484+
Py_buffer view = { 0 };
1485+
1486+
ret = PyObject_GetBuffer(format, &view, PyBUF_SIMPLE);
14841487
Py_DECREF(format);
1485-
PyErr_Format(PyExc_TypeError,
1486-
"Struct() argument 1 must be a str or bytes object, "
1487-
"not %.200s",
1488-
_PyType_Name(Py_TYPE(format)));
1489-
return -1;
1488+
if (ret != 0) {
1489+
PyErr_Format(PyExc_TypeError,
1490+
"Struct() argument 1 must be a str or bytes object, "
1491+
"not %.200s",
1492+
_PyType_Name(Py_TYPE(format)));
1493+
return -1;
1494+
}
1495+
format = PyBytes_FromStringAndSize(view.buf, view.len);
1496+
PyBuffer_Release(&view);
1497+
if (format == NULL) {
1498+
return -1;
1499+
}
14901500
}
14911501

14921502
Py_SETREF(self->s_format, format);

0 commit comments

Comments
 (0)