mirror of https://github.com/python/cpython
The string formatting code has a test to switch to Unicode when %s
sees a Unicode argument. Unfortunately this test was also executed for %r, because %s and %r share almost all of their code. This meant that, if u is a unicode object while repr(u) is an 8-bit string containing ASCII characters, '%r' % u is a *unicode* string containing only ASCII characters! Fixed by executing the test only for %s. Also fixed an error message -- %s argument has non-string str() doesn't make sense for %r, so the error message now differentiates between %s and %r.
This commit is contained in:
parent
06e2a5e052
commit
b00c07f038
|
@ -3858,7 +3858,6 @@ PyString_Format(PyObject *format, PyObject *args)
|
||||||
len = 1;
|
len = 1;
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
case 'r':
|
|
||||||
#ifdef Py_USING_UNICODE
|
#ifdef Py_USING_UNICODE
|
||||||
if (PyUnicode_Check(v)) {
|
if (PyUnicode_Check(v)) {
|
||||||
fmt = fmt_start;
|
fmt = fmt_start;
|
||||||
|
@ -3866,6 +3865,8 @@ PyString_Format(PyObject *format, PyObject *args)
|
||||||
goto unicode;
|
goto unicode;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
/* Fall through */
|
||||||
|
case 'r':
|
||||||
if (c == 's')
|
if (c == 's')
|
||||||
temp = PyObject_Str(v);
|
temp = PyObject_Str(v);
|
||||||
else
|
else
|
||||||
|
@ -3874,7 +3875,9 @@ PyString_Format(PyObject *format, PyObject *args)
|
||||||
goto error;
|
goto error;
|
||||||
if (!PyString_Check(temp)) {
|
if (!PyString_Check(temp)) {
|
||||||
PyErr_SetString(PyExc_TypeError,
|
PyErr_SetString(PyExc_TypeError,
|
||||||
"%s argument has non-string str()");
|
c == 's' ?
|
||||||
|
"%s argument has non-string str()" :
|
||||||
|
"%r argument has non-string repr()");
|
||||||
Py_DECREF(temp);
|
Py_DECREF(temp);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue