]> granicus.if.org Git - python/commitdiff
Issue #19099: The struct module now supports Unicode format strings.
authorSerhiy Storchaka <storchaka@gmail.com>
Sun, 8 Dec 2013 15:44:50 +0000 (17:44 +0200)
committerSerhiy Storchaka <storchaka@gmail.com>
Sun, 8 Dec 2013 15:44:50 +0000 (17:44 +0200)
Lib/test/test_struct.py
Misc/NEWS
Modules/_struct.c

index 2e613f7577bb79a91736c55c01d863762c3f74d3..4811974970ecf20a394cc5d94df3f0ecab57221b 100644 (file)
@@ -574,6 +574,18 @@ class StructTest(unittest.TestCase):
         self.check_sizeof('0s', 1)
         self.check_sizeof('0c', 0)
 
+    def test_unicode_format(self):
+        try:
+            unicode
+        except NameError:
+            self.skipTest('no unicode support')
+        # Issue #19099
+        s = struct.Struct(unichr(ord('I')))
+        self.assertEqual(s.format, 'I')
+        self.assertIs(type(s.format), str)
+        self.assertRaises(ValueError, struct.Struct, unichr(0x80))
+
+
 def test_main():
     support.run_unittest(StructTest)
 
index 928a18ed262b52f67ce08f3430eb8b1d686d6d0e..e3abaec898ff39a5e200fe8d3c73874a2e9b21a7 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -15,6 +15,8 @@ Core and Builtins
 Library
 -------
 
+- Issue #19099: The struct module now supports Unicode format strings.
+
 - Issue #19878: Fix segfault in bz2 module after calling __init__ twice with
   non-existent filename. Initial patch by Vajrasky Kok.
 
index 80569561f988a8291640a78d6fef420d4088ce62..f035847b7ec905b0a6ab4a2c2a8615e3ec3274b0 100644 (file)
@@ -1371,13 +1371,28 @@ s_init(PyObject *self, PyObject *args, PyObject *kwds)
 
     assert(PyStruct_Check(self));
 
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, "S:Struct", kwlist,
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:Struct", kwlist,
                                      &o_format))
         return -1;
 
-    Py_INCREF(o_format);
-    Py_CLEAR(soself->s_format);
-    soself->s_format = o_format;
+    if (PyString_Check(o_format)) {
+        Py_INCREF(o_format);
+        Py_CLEAR(soself->s_format);
+        soself->s_format = o_format;
+    }
+    else if (PyUnicode_Check(o_format)) {
+        PyObject *str = PyUnicode_AsEncodedString(o_format, "ascii", NULL);
+        if (str == NULL)
+            return -1;
+        Py_CLEAR(soself->s_format);
+        soself->s_format = str;
+    }
+    else {
+        PyErr_Format(PyExc_TypeError,
+                     "Struct() argument 1 must be string, not %s",
+                     Py_TYPE(o_format)->tp_name);
+        return -1;
+    }
 
     ret = prepare_s(soself);
     return ret;