mirror of https://github.com/python/cpython
Merged revisions 88697 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/branches/py3k ........ r88697 | victor.stinner | 2011-03-01 23:46:52 +0100 (mar., 01 mars 2011) | 4 lines Issue #11246: Fix PyUnicode_FromFormat("%V") Decode the byte string from UTF-8 (with replace error handler) instead of ISO-8859-1 (in strict mode). Patch written by Ray Allen. ........
This commit is contained in:
parent
d84dfee7c1
commit
2b574a2332
|
@ -1459,6 +1459,19 @@ class UnicodeTest(string_tests.CommonTest,
|
||||||
text = PyUnicode_FromFormat(b'%%A:%A', 'abc\xe9\uabcd\U0010ffff')
|
text = PyUnicode_FromFormat(b'%%A:%A', 'abc\xe9\uabcd\U0010ffff')
|
||||||
self.assertEqual(text, r"%A:'abc\xe9\uabcd\U0010ffff'")
|
self.assertEqual(text, r"%A:'abc\xe9\uabcd\U0010ffff'")
|
||||||
|
|
||||||
|
text = PyUnicode_FromFormat(b'repr=%V', 'abc', b'xyz')
|
||||||
|
self.assertEqual(text, 'repr=abc')
|
||||||
|
|
||||||
|
# Test string decode from parameter of %s using utf-8.
|
||||||
|
# b'\xe4\xba\xba\xe6\xb0\x91' is utf-8 encoded byte sequence of
|
||||||
|
# '\u4eba\u6c11'
|
||||||
|
text = PyUnicode_FromFormat(b'repr=%V', None, b'\xe4\xba\xba\xe6\xb0\x91')
|
||||||
|
self.assertEqual(text, 'repr=\u4eba\u6c11')
|
||||||
|
|
||||||
|
#Test replace error handler.
|
||||||
|
text = PyUnicode_FromFormat(b'repr=%V', None, b'abc\xff')
|
||||||
|
self.assertEqual(text, 'repr=abc\ufffd')
|
||||||
|
|
||||||
# Test PyUnicode_AsWideChar()
|
# Test PyUnicode_AsWideChar()
|
||||||
def test_aswidechar(self):
|
def test_aswidechar(self):
|
||||||
from _testcapi import unicode_aswidechar
|
from _testcapi import unicode_aswidechar
|
||||||
|
|
|
@ -10,6 +10,10 @@ What's New in Python 3.2.1?
|
||||||
Core and Builtins
|
Core and Builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Issue #11246: Fix PyUnicode_FromFormat("%V") to decode the byte string from
|
||||||
|
UTF-8 (with replace error handler) instead of ISO-8859-1 (in strict mode).
|
||||||
|
Patch written by Ray Allen.
|
||||||
|
|
||||||
- Issue #11286: Raise a ValueError from calling PyMemoryView_FromBuffer with
|
- Issue #11286: Raise a ValueError from calling PyMemoryView_FromBuffer with
|
||||||
a buffer struct having a NULL data pointer.
|
a buffer struct having a NULL data pointer.
|
||||||
|
|
||||||
|
|
|
@ -752,7 +752,7 @@ PyUnicode_FromFormatV(const char *format, va_list vargs)
|
||||||
if (*f == '%') {
|
if (*f == '%') {
|
||||||
if (*(f+1)=='%')
|
if (*(f+1)=='%')
|
||||||
continue;
|
continue;
|
||||||
if (*(f+1)=='S' || *(f+1)=='R' || *(f+1)=='A')
|
if (*(f+1)=='S' || *(f+1)=='R' || *(f+1)=='A' || *(f+1) == 'V')
|
||||||
++callcount;
|
++callcount;
|
||||||
while (Py_ISDIGIT((unsigned)*f))
|
while (Py_ISDIGIT((unsigned)*f))
|
||||||
width = (width*10) + *f++ - '0';
|
width = (width*10) + *f++ - '0';
|
||||||
|
@ -872,12 +872,20 @@ PyUnicode_FromFormatV(const char *format, va_list vargs)
|
||||||
{
|
{
|
||||||
PyObject *obj = va_arg(count, PyObject *);
|
PyObject *obj = va_arg(count, PyObject *);
|
||||||
const char *str = va_arg(count, const char *);
|
const char *str = va_arg(count, const char *);
|
||||||
|
PyObject *str_obj;
|
||||||
assert(obj || str);
|
assert(obj || str);
|
||||||
assert(!obj || PyUnicode_Check(obj));
|
assert(!obj || PyUnicode_Check(obj));
|
||||||
if (obj)
|
if (obj) {
|
||||||
n += PyUnicode_GET_SIZE(obj);
|
n += PyUnicode_GET_SIZE(obj);
|
||||||
else
|
*callresult++ = NULL;
|
||||||
n += strlen(str);
|
}
|
||||||
|
else {
|
||||||
|
str_obj = PyUnicode_DecodeUTF8(str, strlen(str), "replace");
|
||||||
|
if (!str_obj)
|
||||||
|
goto fail;
|
||||||
|
n += PyUnicode_GET_SIZE(str_obj);
|
||||||
|
*callresult++ = str_obj;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'S':
|
case 'S':
|
||||||
|
@ -1080,14 +1088,18 @@ PyUnicode_FromFormatV(const char *format, va_list vargs)
|
||||||
case 'V':
|
case 'V':
|
||||||
{
|
{
|
||||||
PyObject *obj = va_arg(vargs, PyObject *);
|
PyObject *obj = va_arg(vargs, PyObject *);
|
||||||
const char *str = va_arg(vargs, const char *);
|
va_arg(vargs, const char *);
|
||||||
if (obj) {
|
if (obj) {
|
||||||
Py_ssize_t size = PyUnicode_GET_SIZE(obj);
|
Py_ssize_t size = PyUnicode_GET_SIZE(obj);
|
||||||
Py_UNICODE_COPY(s, PyUnicode_AS_UNICODE(obj), size);
|
Py_UNICODE_COPY(s, PyUnicode_AS_UNICODE(obj), size);
|
||||||
s += size;
|
s += size;
|
||||||
} else {
|
} else {
|
||||||
appendstring(str);
|
Py_UNICODE_COPY(s, PyUnicode_AS_UNICODE(*callresult),
|
||||||
|
PyUnicode_GET_SIZE(*callresult));
|
||||||
|
s += PyUnicode_GET_SIZE(*callresult);
|
||||||
|
Py_DECREF(*callresult);
|
||||||
}
|
}
|
||||||
|
++callresult;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'S':
|
case 'S':
|
||||||
|
@ -1144,7 +1156,7 @@ PyUnicode_FromFormatV(const char *format, va_list vargs)
|
||||||
if (callresults) {
|
if (callresults) {
|
||||||
PyObject **callresult2 = callresults;
|
PyObject **callresult2 = callresults;
|
||||||
while (callresult2 < callresult) {
|
while (callresult2 < callresult) {
|
||||||
Py_DECREF(*callresult2);
|
Py_XDECREF(*callresult2);
|
||||||
++callresult2;
|
++callresult2;
|
||||||
}
|
}
|
||||||
PyObject_Free(callresults);
|
PyObject_Free(callresults);
|
||||||
|
|
Loading…
Reference in New Issue