Index: Objects/unicodeobject.c =================================================================== --- Objects/unicodeobject.c (Revision 84223) +++ Objects/unicodeobject.c (Arbeitskopie) @@ -1234,8 +1234,7 @@ const char *encoding, const char *errors) { - const char *s = NULL; - Py_ssize_t len; + Py_buffer char_buffer; PyObject *v; if (obj == NULL) { @@ -1243,44 +1242,44 @@ return NULL; } + /* Decoding bytes objects is the most common case and should be fast */ + if (PyBytes_Check(obj)) { + if (PyBytes_GET_SIZE(obj) == 0) { + Py_INCREF(unicode_empty); + v = (PyObject *)unicode_empty; + } + else { + v = PyUnicode_Decode( + PyBytes_AS_STRING(obj), PyBytes_GET_SIZE(obj), + encoding, errors); + } + return v; + } + if (PyUnicode_Check(obj)) { PyErr_SetString(PyExc_TypeError, "decoding str is not supported"); return NULL; } - /* Coerce object */ - if (PyBytes_Check(obj)) { - s = PyBytes_AS_STRING(obj); - len = PyBytes_GET_SIZE(obj); + /* Retrieve a char buffer view through the PEP 3118 buffer interface */ + if (PyObject_GetBuffer(obj, &char_buffer, PyBUF_SIMPLE) < 0) { + PyErr_Format(PyExc_TypeError, + "coercing to str: need bytes, bytearray or char buffer, " + "%.80s found", + Py_TYPE(obj)->tp_name); + return NULL; } - else if (PyByteArray_Check(obj)) { - s = PyByteArray_AS_STRING(obj); - len = PyByteArray_GET_SIZE(obj); - } - else if (PyObject_AsCharBuffer(obj, &s, &len)) { - /* Overwrite the error message with something more useful in - case of a TypeError. */ - if (PyErr_ExceptionMatches(PyExc_TypeError)) - PyErr_Format(PyExc_TypeError, - "coercing to str: need bytes, bytearray or char buffer, " - "%.80s found", - Py_TYPE(obj)->tp_name); - goto onError; - } - /* Convert to Unicode */ - if (len == 0) { + if (char_buffer.len == 0) { Py_INCREF(unicode_empty); v = (PyObject *)unicode_empty; } else - v = PyUnicode_Decode(s, len, encoding, errors); + v = PyUnicode_Decode((char*)char_buffer.buf, char_buffer.len, encoding, errors); + PyBuffer_Release(&char_buffer); return v; - - onError: - return NULL; } /* Convert encoding to lower case and replace '_' with '-' in order to