bpo-21071: struct.Struct.format type is now str (#845)
diff --git a/Doc/library/struct.rst b/Doc/library/struct.rst
index bb32a65..2d0866c 100644
--- a/Doc/library/struct.rst
+++ b/Doc/library/struct.rst
@@ -443,6 +443,9 @@
The format string used to construct this Struct object.
+ .. versionchanged:: 3.7
+ The format string type is now :class:`str` instead of :class:`bytes`.
+
.. attribute:: size
The calculated size of the struct (and hence of the bytes object produced
diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst
index 8c1636b..580da62 100644
--- a/Doc/whatsnew/3.7.rst
+++ b/Doc/whatsnew/3.7.rst
@@ -429,6 +429,9 @@
``makedirs()``.
(Contributed by Serhiy Storchaka in :issue:`19930`.)
+* The :attr:`struct.Struct.format` type is now :class:`str` instead of
+ :class:`bytes`. (Contributed by Victor Stinner in :issue:`21071`.)
+
CPython bytecode changes
------------------------
diff --git a/Lib/test/test_struct.py b/Lib/test/test_struct.py
index b2a5f42..a896468 100644
--- a/Lib/test/test_struct.py
+++ b/Lib/test/test_struct.py
@@ -618,6 +618,14 @@
# Shouldn't crash.
self.assertEqual(struct.unpack(b'b', b'a'), (b'a'[0],))
+ def test_format_attr(self):
+ s = struct.Struct('=i2H')
+ self.assertEqual(s.format, '=i2H')
+
+ # use a bytes string
+ s2 = struct.Struct(s.format.encode())
+ self.assertEqual(s2.format, s.format)
+
class UnpackIteratorTest(unittest.TestCase):
"""
diff --git a/Misc/NEWS b/Misc/NEWS
index 4b6b8fc..33a1593 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -374,6 +374,9 @@
Library
-------
+- bpo-21071: struct.Struct.format type is now :class:`str` instead of
+ :class:`bytes`.
+
- bpo-29212: Fix concurrent.futures.thread.ThreadPoolExecutor threads to have
a non repr() based thread name by default when no thread_name_prefix is
supplied. They will now identify themselves as "ThreadPoolExecutor-y_n".
diff --git a/Modules/_struct.c b/Modules/_struct.c
index 46e7b40..b4febf7 100644
--- a/Modules/_struct.c
+++ b/Modules/_struct.c
@@ -1957,8 +1957,8 @@
static PyObject *
s_get_format(PyStructObject *self, void *unused)
{
- Py_INCREF(self->s_format);
- return self->s_format;
+ return PyUnicode_FromStringAndSize(PyBytes_AS_STRING(self->s_format),
+ PyBytes_GET_SIZE(self->s_format));
}
static PyObject *