[Python-checkins] cpython (merge 3.5 -> 3.6): Issue #28808: PyUnicode_CompareWithASCIIString() now never raises exceptions.

serhiy.storchaka python-checkins at python.org
Mon Dec 5 17:20:50 EST 2016


https://hg.python.org/cpython/rev/5bdc8e1a50c8
changeset:   105467:5bdc8e1a50c8
branch:      3.6
parent:      105459:e33245800f1a
parent:      105466:b431d39da67f
user:        Serhiy Storchaka <storchaka at gmail.com>
date:        Tue Dec 06 00:17:45 2016 +0200
summary:
  Issue #28808: PyUnicode_CompareWithASCIIString() now never raises exceptions.

files:
  Doc/c-api/unicode.rst   |   3 +--
  Include/unicodeobject.h |   2 +-
  Misc/NEWS               |   5 +++++
  Objects/unicodeobject.c |  18 ++++++++++++++++--
  4 files changed, 23 insertions(+), 5 deletions(-)


diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst
--- a/Doc/c-api/unicode.rst
+++ b/Doc/c-api/unicode.rst
@@ -1657,8 +1657,7 @@
    ASCII-encoded strings, but the function interprets the input string as
    ISO-8859-1 if it contains non-ASCII characters.
 
-   This function returns ``-1`` upon failure, so one should call
-   :c:func:`PyErr_Occurred` to check for errors.
+   This function does not raise exceptions.
 
 
 .. c:function:: PyObject* PyUnicode_RichCompare(PyObject *left,  PyObject *right,  int op)
diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h
--- a/Include/unicodeobject.h
+++ b/Include/unicodeobject.h
@@ -2051,7 +2051,7 @@
    equal, and greater than, respectively.  It is best to pass only
    ASCII-encoded strings, but the function interprets the input string as
    ISO-8859-1 if it contains non-ASCII characters.
-   Raise an exception and return -1 on error. */
+   This function does not raise exceptions. */
 
 PyAPI_FUNC(int) PyUnicode_CompareWithASCIIString(
     PyObject *left,
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -36,6 +36,11 @@
 
 - Issue #28843: Fix asyncio C Task to handle exceptions __traceback__.
 
+C API
+-----
+
+- Issue #28808: PyUnicode_CompareWithASCIIString() now never raises exceptions.
+
 Documentation
 -------------
 
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -11011,10 +11011,24 @@
     Py_ssize_t i;
     int kind;
     Py_UCS4 chr;
+    const unsigned char *ustr = (const unsigned char *)str;
 
     assert(_PyUnicode_CHECK(uni));
-    if (PyUnicode_READY(uni) == -1)
-        return -1;
+    if (!PyUnicode_IS_READY(uni)) {
+        const wchar_t *ws = _PyUnicode_WSTR(uni);
+        /* Compare Unicode string and source character set string */
+        for (i = 0; (chr = ws[i]) && ustr[i]; i++) {
+            if (chr != ustr[i])
+                return (chr < ustr[i]) ? -1 : 1;
+        }
+        /* This check keeps Python strings that end in '\0' from comparing equal
+         to C strings identical up to that point. */
+        if (_PyUnicode_WSTR_LENGTH(uni) != i || chr)
+            return 1; /* uni is longer */
+        if (ustr[i])
+            return -1; /* str is longer */
+        return 0;
+    }
     kind = PyUnicode_KIND(uni);
     if (kind == PyUnicode_1BYTE_KIND) {
         const void *data = PyUnicode_1BYTE_DATA(uni);

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list