bpo-21071: struct.Struct.format type is now str (#845)
authorVictor Stinner <victor.stinner@gmail.com>
Fri, 23 Jun 2017 13:11:12 +0000 (15:11 +0200)
committerGitHub <noreply@github.com>
Fri, 23 Jun 2017 13:11:12 +0000 (15:11 +0200)
Doc/library/struct.rst
Doc/whatsnew/3.7.rst
Lib/test/test_struct.py
Misc/NEWS
Modules/_struct.c

index bb32a65d2e400505032f9b019f621b1930c0d823..2d0866c7e09e7c2f76c0934bc188a1d082024c09 100644 (file)
@@ -443,6 +443,9 @@ The :mod:`struct` module also defines the following type:
 
       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
index 8c1636bd778cfa5119579b2fb5a417b228480393..580da6238953c48b1e3dde4181085060d2f3ed14 100644 (file)
@@ -429,6 +429,9 @@ Changes in the Python API
   ``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
 ------------------------
index b2a5f429e0b94b26a6eedfd677b210ef486e7ff2..a896468848e4fd309398825b7dcb63ed332a2a01 100644 (file)
@@ -618,6 +618,14 @@ class StructTest(unittest.TestCase):
         # 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):
     """
index 4b6b8fcffb2930afd2159ebb866b38a19da69c87..33a1593369e84bf0ad8adbb681fa2b4cd832daaf 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -374,6 +374,9 @@ Extension Modules
 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".
index 46e7b4071b95a4fe50b394a4d747130887d87f22..b4febf7750321a4fef4d1193dfd60a58153848b9 100644 (file)
@@ -1957,8 +1957,8 @@ s_pack_into(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames
 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 *