diff -r 94628dc3b05c Lib/test/test_struct.py --- a/Lib/test/test_struct.py Mon Sep 30 21:50:21 2013 -0400 +++ b/Lib/test/test_struct.py Tue Oct 01 11:51:20 2013 +0800 @@ -574,6 +574,14 @@ self.check_sizeof('0s', 1) self.check_sizeof('0c', 0) + def test_ascii_range_unicode_format(self): + # issue 19099 + struct._clearcache() + self.assertEqual(struct.pack(u'B', 1), '\x01') + + def test_outside_ascii_range_unicode_format(self): + self.assertRaises(struct.error, struct.pack, u'\xff', 1) + def test_main(): support.run_unittest(StructTest) diff -r 94628dc3b05c Modules/_struct.c --- a/Modules/_struct.c Mon Sep 30 21:50:21 2013 -0400 +++ b/Modules/_struct.c Tue Oct 01 11:51:20 2013 +0800 @@ -1856,12 +1856,24 @@ { PyObject *s_object, *fmt, *newargs, *result; Py_ssize_t n = PyTuple_GET_SIZE(args); + const char* s; if (n == 0) { PyErr_SetString(PyExc_TypeError, "missing format argument"); return NULL; } fmt = PyTuple_GET_ITEM(args, 0); + /* Accept ascii-range unicode argument, e.g. struct.pack(u'b', 1) */ + if (PyUnicode_Check(fmt)) { + s = PyString_AsString(fmt); + if (s == NULL) { + PyErr_SetString(StructError, "bad char in struct format"); + return NULL; + } else { + fmt = PyString_FromString(s); + Py_DECREF(s); + } + } newargs = PyTuple_GetSlice(args, 1, n); if (newargs == NULL) return NULL;