Index: Objects/stringlib/string_format.h =================================================================== --- Objects/stringlib/string_format.h (révision 78814) +++ Objects/stringlib/string_format.h (copie de travail) @@ -578,6 +578,12 @@ this optimization for unicode. This could be fixed, but it's a hassle. */ #else + if (PyUnicode_CheckExact(fieldobj)) + { + /* raise an UnicodeEncodeError */ + (void)PyUnicode_Decode("\xff", 1, "ascii", "strict"); + return 0; + } if (PyString_CheckExact(fieldobj)) formatter = _PyBytes_FormatAdvanced; else if (PyInt_CheckExact(fieldobj)) Index: Objects/stringobject.c =================================================================== --- Objects/stringobject.c (révision 78814) +++ Objects/stringobject.c (copie de travail) @@ -3617,6 +3617,35 @@ \n\ "); +static PyObject * +string_format(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *result, *unicode, *format; + + result = do_string_format(self, args, kwargs); + if (result != NULL) + return result; + + if (!PyErr_ExceptionMatches(PyExc_UnicodeError)) + return NULL; + + PyErr_Clear(); + unicode = PyUnicode_Decode(PyString_AS_STRING(self), PyString_GET_SIZE(self), NULL, NULL); + if (unicode == NULL) + return NULL; + + format = PyObject_GetAttrString(unicode, "format"); + if (format == NULL) { + Py_DECREF(unicode); + return NULL; + } + + result = PyObject_Call(format, args, kwargs); + + Py_DECREF(format); + Py_DECREF(unicode); + return result; +} static PyMethodDef string_methods[] = { @@ -3661,7 +3690,7 @@ {"rjust", (PyCFunction)string_rjust, METH_VARARGS, rjust__doc__}, {"center", (PyCFunction)string_center, METH_VARARGS, center__doc__}, {"zfill", (PyCFunction)string_zfill, METH_VARARGS, zfill__doc__}, - {"format", (PyCFunction) do_string_format, METH_VARARGS | METH_KEYWORDS, format__doc__}, + {"format", (PyCFunction) string_format, METH_VARARGS | METH_KEYWORDS, format__doc__}, {"__format__", (PyCFunction) string__format__, METH_VARARGS, p_format__doc__}, {"_formatter_field_name_split", (PyCFunction) formatter_field_name_split, METH_NOARGS}, {"_formatter_parser", (PyCFunction) formatter_parser, METH_NOARGS}, Index: Lib/test/test_unicode.py =================================================================== --- Lib/test/test_unicode.py (révision 78814) +++ Lib/test/test_unicode.py (copie de travail) @@ -1143,13 +1143,12 @@ self.assertRaises(ValueError, u"{0:=s}".format, u'') # test combining string and unicode - self.assertEqual(u"foo{0}".format('bar'), u'foobar') - # This will try to convert the argument from unicode to str, which - # will succeed - self.assertEqual("foo{0}".format(u'bar'), 'foobar') - # This will try to convert the argument from unicode to str, which - # will fail - self.assertRaises(UnicodeEncodeError, "foo{0}".format, u'\u1000bar') + def check(a, b): + self.assertEqual(a, b) + self.assertEqual(type(a), type(b)) + check(u"foo{0}".format('bar'), u'foobar') + check("foo{0}".format(u'bar'), u'foobar') + check("foo{0}".format(u'\u1000bar'), u'foo\u1000bar') def test_format_auto_numbering(self): class C: