[Python-checkins] r84394 - in python/branches/py3k: Misc/ACKS Misc/NEWS Objects/unicodeobject.c

antoine.pitrou python-checkins at python.org
Wed Sep 1 17:10:13 CEST 2010


Author: antoine.pitrou
Date: Wed Sep  1 17:10:12 2010
New Revision: 84394

Log:
Issue #7415: PyUnicode_FromEncodedObject() now uses the new buffer API
properly.  Patch by Stefan Behnel.



Modified:
   python/branches/py3k/Misc/ACKS
   python/branches/py3k/Misc/NEWS
   python/branches/py3k/Objects/unicodeobject.c

Modified: python/branches/py3k/Misc/ACKS
==============================================================================
--- python/branches/py3k/Misc/ACKS	(original)
+++ python/branches/py3k/Misc/ACKS	Wed Sep  1 17:10:12 2010
@@ -62,6 +62,7 @@
 Robin Becker
 Neal Becker
 Bill Bedford
+Stefan Behnel
 Reimer Behrends
 Ben Bell
 Thomas Bellman

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Wed Sep  1 17:10:12 2010
@@ -12,6 +12,9 @@
 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.

Modified: python/branches/py3k/Objects/unicodeobject.c
==============================================================================
--- python/branches/py3k/Objects/unicodeobject.c	(original)
+++ python/branches/py3k/Objects/unicodeobject.c	Wed Sep  1 17:10:12 2010
@@ -1234,8 +1234,7 @@
                                       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 @@
         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


More information about the Python-checkins mailing list