# HG changeset patch
# Parent cdc3837cb1fcfc4273b46e84c533ec7e91246b71
Issue 21071: Struct.format is now a str
diff -r cdc3837cb1fc Doc/library/struct.rst
--- a/Doc/library/struct.rst Tue Dec 16 03:21:54 2014 -0500
+++ b/Doc/library/struct.rst Thu Dec 18 05:23:42 2014 +0000
@@ -420,6 +420,10 @@
The format string used to construct this Struct object.
+ .. versionchanged:: 3.5
+ Previously this was a :class:`bytes` object;
+ now it is a :class:`str` object.
+
.. attribute:: size
The calculated size of the struct (and hence of the bytes object produced
diff -r cdc3837cb1fc Lib/test/test_struct.py
--- a/Lib/test/test_struct.py Tue Dec 16 03:21:54 2014 -0500
+++ b/Lib/test/test_struct.py Thu Dec 18 05:23:42 2014 +0000
@@ -589,6 +589,16 @@
self.check_sizeof('20p', 1)
self.check_sizeof('0s', 1)
self.check_sizeof('0c', 0)
+
+ def test_format_attr(self):
+ """Make sure the "format" attribute is a text string"""
+ self.assertEqual("x", struct.Struct("x").format)
+
+ def test_format_utf(self):
+ """Check error handling for unencodable format string"""
+ surrogate = "\uDC80"
+ self.assertRaises(UnicodeError, struct.pack, surrogate)
+ self.assertRaises(UnicodeError, struct.Struct, surrogate)
class UnpackIteratorTest(unittest.TestCase):
diff -r cdc3837cb1fc Modules/_struct.c
--- a/Modules/_struct.c Tue Dec 16 03:21:54 2014 -0500
+++ b/Modules/_struct.c Thu Dec 18 05:23:42 2014 +0000
@@ -1266,7 +1266,10 @@
Py_ssize_t size, len, num, itemsize;
size_t ncodes;
- fmt = PyBytes_AS_STRING(self->s_format);
+ fmt = PyUnicode_AsUTF8(self->s_format);
+ if (fmt == NULL) {
+ return -1;
+ }
f = whichtable((char **)&fmt);
@@ -1419,8 +1422,10 @@
&o_format))
return -1;
- if (PyUnicode_Check(o_format)) {
- o_format = PyUnicode_AsASCIIString(o_format);
+ if (PyBytes_Check(o_format)) {
+ o_format = PyUnicode_DecodeASCII(
+ PyBytes_AS_STRING(o_format), PyBytes_GET_SIZE(o_format),
+ "strict");
if (o_format == NULL)
return -1;
}
@@ -1429,10 +1434,10 @@
Py_INCREF(o_format);
}
- if (!PyBytes_Check(o_format)) {
+ if (!PyUnicode_Check(o_format)) {
Py_DECREF(o_format);
PyErr_Format(PyExc_TypeError,
- "Struct() argument 1 must be a bytes object, not %.200s",
+ "Struct() argument 1 must be a string object, not %.200s",
Py_TYPE(o_format)->tp_name);
return -1;
}
@@ -2221,9 +2226,8 @@
PyDoc_STRVAR(module_doc,
"Functions to convert between Python values and C structs.\n\
-Python bytes objects are used to hold the data representing the C struct\n\
-and also as format strings (explained below) to describe the layout of data\n\
-in the C struct.\n\
+Python bytes objects are used to hold the data representing the C struct.\n\
+Format strings describe the layout of data in the C struct.\n\
\n\
The optional first format char indicates byte order, size and alignment:\n\
@: native order, size & alignment (default)\n\