Issue #7415: PyUnicode_FromEncodedObject() now uses the new buffer API

properly.  Patch by Stefan Behnel.
This commit is contained in:
Antoine Pitrou 2010-09-01 15:10:12 +00:00
parent f68c2a701b
commit b0fa831d1e
3 changed files with 30 additions and 27 deletions

View file

@ -62,6 +62,7 @@ David Beazley
Robin Becker Robin Becker
Neal Becker Neal Becker
Bill Bedford Bill Bedford
Stefan Behnel
Reimer Behrends Reimer Behrends
Ben Bell Ben Bell
Thomas Bellman Thomas Bellman

View file

@ -12,6 +12,9 @@ What's New in Python 3.2 Alpha 2?
Core and Builtins Core and Builtins
----------------- -----------------
- Issue #7415: PyUnicode_FromEncodedObject() now uses the new buffer API
properly. Patch by Stefan Behnel.
- Issue #5553: The Py_LOCAL_INLINE macro now results in inlining on - Issue #5553: The Py_LOCAL_INLINE macro now results in inlining on
most platforms. Previously, it online inlined when using Microsoft most platforms. Previously, it online inlined when using Microsoft
Visual C. Visual C.

View file

@ -1234,8 +1234,7 @@ PyObject *PyUnicode_FromEncodedObject(register PyObject *obj,
const char *encoding, const char *encoding,
const char *errors) const char *errors)
{ {
const char *s = NULL; Py_buffer buffer;
Py_ssize_t len;
PyObject *v; PyObject *v;
if (obj == NULL) { if (obj == NULL) {
@ -1243,44 +1242,44 @@ PyObject *PyUnicode_FromEncodedObject(register PyObject *obj,
return NULL; 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)) { if (PyUnicode_Check(obj)) {
PyErr_SetString(PyExc_TypeError, PyErr_SetString(PyExc_TypeError,
"decoding str is not supported"); "decoding str is not supported");
return NULL; return NULL;
} }
/* Coerce object */ /* Retrieve a bytes buffer view through the PEP 3118 buffer interface */
if (PyBytes_Check(obj)) { if (PyObject_GetBuffer(obj, &buffer, PyBUF_SIMPLE) < 0) {
s = PyBytes_AS_STRING(obj); PyErr_Format(PyExc_TypeError,
len = PyBytes_GET_SIZE(obj); "coercing to str: need bytes, bytearray "
} "or buffer-like object, %.80s found",
else if (PyByteArray_Check(obj)) { Py_TYPE(obj)->tp_name);
s = PyByteArray_AS_STRING(obj); return NULL;
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 (buffer.len == 0) {
if (len == 0) {
Py_INCREF(unicode_empty); Py_INCREF(unicode_empty);
v = (PyObject *)unicode_empty; v = (PyObject *) unicode_empty;
} }
else else
v = PyUnicode_Decode(s, len, encoding, errors); v = PyUnicode_Decode((char*) buffer.buf, buffer.len, encoding, errors);
PyBuffer_Release(&buffer);
return v; return v;
onError:
return NULL;
} }
/* Convert encoding to lower case and replace '_' with '-' in order to /* Convert encoding to lower case and replace '_' with '-' in order to