Skip to content

Commit d0f9e95

Browse files
Issue #28808: PyUnicode_CompareWithASCIIString() now never raises exceptions.
2 parents ab909ba + 25c69c0 commit d0f9e95

4 files changed

Lines changed: 20 additions & 5 deletions

File tree

Doc/c-api/unicode.rst

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1657,8 +1657,7 @@ They all return *NULL* or ``-1`` if an exception occurs.
16571657
ASCII-encoded strings, but the function interprets the input string as
16581658
ISO-8859-1 if it contains non-ASCII characters.
16591659
1660-
This function returns ``-1`` upon failure, so one should call
1661-
:c:func:`PyErr_Occurred` to check for errors.
1660+
This function does not raise exceptions.
16621661
16631662
16641663
.. c:function:: PyObject* PyUnicode_RichCompare(PyObject *left, PyObject *right, int op)

Include/unicodeobject.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2055,7 +2055,7 @@ PyAPI_FUNC(int) _PyUnicode_EqualToASCIIId(
20552055
equal, and greater than, respectively. It is best to pass only
20562056
ASCII-encoded strings, but the function interprets the input string as
20572057
ISO-8859-1 if it contains non-ASCII characters.
2058-
Raise an exception and return -1 on error. */
2058+
This function does not raise exceptions. */
20592059

20602060
PyAPI_FUNC(int) PyUnicode_CompareWithASCIIString(
20612061
PyObject *left,

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,8 @@ Windows
480480
C API
481481
-----
482482

483+
- Issue #28808: PyUnicode_CompareWithASCIIString() now never raises exceptions.
484+
483485
- Issue #28761: The fields name and doc of structures PyMemberDef, PyGetSetDef,
484486
PyStructSequence_Field, PyStructSequence_Desc, and wrapperbase are now of
485487
type ``const char *`` rather of ``char *``.

Objects/unicodeobject.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10977,10 +10977,24 @@ PyUnicode_CompareWithASCIIString(PyObject* uni, const char* str)
1097710977
Py_ssize_t i;
1097810978
int kind;
1097910979
Py_UCS4 chr;
10980+
const unsigned char *ustr = (const unsigned char *)str;
1098010981

1098110982
assert(_PyUnicode_CHECK(uni));
10982-
if (PyUnicode_READY(uni) == -1)
10983-
return -1;
10983+
if (!PyUnicode_IS_READY(uni)) {
10984+
const wchar_t *ws = _PyUnicode_WSTR(uni);
10985+
/* Compare Unicode string and source character set string */
10986+
for (i = 0; (chr = ws[i]) && ustr[i]; i++) {
10987+
if (chr != ustr[i])
10988+
return (chr < ustr[i]) ? -1 : 1;
10989+
}
10990+
/* This check keeps Python strings that end in '\0' from comparing equal
10991+
to C strings identical up to that point. */
10992+
if (_PyUnicode_WSTR_LENGTH(uni) != i || chr)
10993+
return 1; /* uni is longer */
10994+
if (ustr[i])
10995+
return -1; /* str is longer */
10996+
return 0;
10997+
}
1098410998
kind = PyUnicode_KIND(uni);
1098510999
if (kind == PyUnicode_1BYTE_KIND) {
1098611000
const void *data = PyUnicode_1BYTE_DATA(uni);

0 commit comments

Comments
 (0)