summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2010-09-01 15:10:12 (GMT)
committerAntoine Pitrou <solipsis@pitrou.net>2010-09-01 15:10:12 (GMT)
commitb0fa831d1e073624d28aa403496f122e2f35697a (patch)
tree4aab58985ebc949c482407f29f056e136d73bfb2
parentf68c2a701bbca88da1299efe4aba84699827e791 (diff)
downloadcpython-b0fa831d1e073624d28aa403496f122e2f35697a.zip
cpython-b0fa831d1e073624d28aa403496f122e2f35697a.tar.gz
cpython-b0fa831d1e073624d28aa403496f122e2f35697a.tar.bz2
Issue #7415: PyUnicode_FromEncodedObject() now uses the new buffer API
properly. Patch by Stefan Behnel.
-rw-r--r--Misc/ACKS1
-rw-r--r--Misc/NEWS3
-rw-r--r--Objects/unicodeobject.c53
3 files changed, 30 insertions, 27 deletions
diff --git a/Misc/ACKS b/Misc/ACKS
index d841e1a..a1a42a5 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -62,6 +62,7 @@ David Beazley
Robin Becker
Neal Becker
Bill Bedford
+Stefan Behnel
Reimer Behrends
Ben Bell
Thomas Bellman
diff --git a/Misc/NEWS b/Misc/NEWS
index 1055165..ceac14e 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,9 @@ What's New in Python 3.2 Alpha 2?
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
most platforms. Previously, it online inlined when using Microsoft
Visual C.
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 4c4b43c..753b465 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -1234,8 +1234,7 @@ PyObject *PyUnicode_FromEncodedObject(register PyObject *obj,
const char *encoding,
const char *errors)
{
- const char *s = NULL;
- Py_ssize_t len;
+ Py_buffer buffer;
PyObject *v;
if (obj == NULL) {
@@ -1243,44 +1242,44 @@ PyObject *PyUnicode_FromEncodedObject(register PyObject *obj,
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);
- }
- 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;
+ /* Retrieve a bytes buffer view through the PEP 3118 buffer interface */
+ if (PyObject_GetBuffer(obj, &buffer, PyBUF_SIMPLE) < 0) {
+ PyErr_Format(PyExc_TypeError,
+ "coercing to str: need bytes, bytearray "
+ "or buffer-like object, %.80s found",
+ Py_TYPE(obj)->tp_name);
+ return NULL;
}
- /* Convert to Unicode */
- if (len == 0) {
+ if (buffer.len == 0) {
Py_INCREF(unicode_empty);
- v = (PyObject *)unicode_empty;
+ v = (PyObject *) unicode_empty;
}
else
- v = PyUnicode_Decode(s, len, encoding, errors);
+ v = PyUnicode_Decode((char*) buffer.buf, buffer.len, encoding, errors);
+ PyBuffer_Release(&buffer);
return v;
-
- onError:
- return NULL;
}
/* Convert encoding to lower case and replace '_' with '-' in order to