diff -r dd55d54b2a15 Lib/test/test_struct.py --- a/Lib/test/test_struct.py Sun Sep 29 18:57:42 2013 -0700 +++ b/Lib/test/test_struct.py Tue Oct 01 11:24:15 2013 +0300 @@ -574,6 +574,14 @@ self.check_sizeof('0s', 1) self.check_sizeof('0c', 0) + def test_unicode_format(self): + # Issue #19099 + s = struct.Struct(u'I') + self.assertEqual(s.format, 'I') + self.assertIs(type(s.format), str) + self.assertRaises(ValueError, struct.Struct, u'\x80') + + def test_main(): support.run_unittest(StructTest) diff -r dd55d54b2a15 Misc/NEWS --- a/Misc/NEWS Sun Sep 29 18:57:42 2013 -0700 +++ b/Misc/NEWS Tue Oct 01 11:24:15 2013 +0300 @@ -32,6 +32,8 @@ Library ------- +- Issue #19099: The struct module now supports Unicode format strings. + - Properly initialize all fields of a SSL object after allocation. - Issue #4366: Fix building extensions on all platforms when --enable-shared diff -r dd55d54b2a15 Modules/_struct.c --- a/Modules/_struct.c Sun Sep 29 18:57:42 2013 -0700 +++ b/Modules/_struct.c Tue Oct 01 11:24:15 2013 +0300 @@ -1371,13 +1371,28 @@ 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;