Skip to content

Commit 419967b

Browse files
Issue python#28808: PyUnicode_CompareWithASCIIString() now never raises exceptions.
1 parent 7bc01c3 commit 419967b

File tree

4 files changed

+20
-5
lines changed

4 files changed

+20
-5
lines changed

Doc/c-api/unicode.rst

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1652,8 +1652,7 @@ They all return *NULL* or ``-1`` if an exception occurs.
16521652
ASCII-encoded strings, but the function interprets the input string as
16531653
ISO-8859-1 if it contains non-ASCII characters.
16541654
1655-
This function returns ``-1`` upon failure, so one should call
1656-
:c:func:`PyErr_Occurred` to check for errors.
1655+
This function does not raise exceptions.
16571656
16581657
16591658
.. 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
@@ -2023,7 +2023,7 @@ PyAPI_FUNC(int) _PyUnicode_EqualToASCIIId(
20232023
equal, and greater than, respectively. It is best to pass only
20242024
ASCII-encoded strings, but the function interprets the input string as
20252025
ISO-8859-1 if it contains non-ASCII characters.
2026-
Raise an exception and return -1 on error. */
2026+
This function does not raise exceptions. */
20272027

20282028
PyAPI_FUNC(int) PyUnicode_CompareWithASCIIString(
20292029
PyObject *left,

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,8 @@ IDLE
506506
C API
507507
-----
508508

509+
- Issue #28808: PyUnicode_CompareWithASCIIString() now never raises exceptions.
510+
509511
- Issue #26754: PyUnicode_FSDecoder() accepted a filename argument encoded as
510512
an iterable of integers. Now only strings and bytes-like objects are accepted.
511513

Objects/unicodeobject.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10793,10 +10793,24 @@ PyUnicode_CompareWithASCIIString(PyObject* uni, const char* str)
1079310793
Py_ssize_t i;
1079410794
int kind;
1079510795
Py_UCS4 chr;
10796+
const unsigned char *ustr = (const unsigned char *)str;
1079610797

1079710798
assert(_PyUnicode_CHECK(uni));
10798-
if (PyUnicode_READY(uni) == -1)
10799-
return -1;
10799+
if (!PyUnicode_IS_READY(uni)) {
10800+
const wchar_t *ws = _PyUnicode_WSTR(uni);
10801+
/* Compare Unicode string and source character set string */
10802+
for (i = 0; (chr = ws[i]) && ustr[i]; i++) {
10803+
if (chr != ustr[i])
10804+
return (chr < ustr[i]) ? -1 : 1;
10805+
}
10806+
/* This check keeps Python strings that end in '\0' from comparing equal
10807+
to C strings identical up to that point. */
10808+
if (_PyUnicode_WSTR_LENGTH(uni) != i || chr)
10809+
return 1; /* uni is longer */
10810+
if (ustr[i])
10811+
return -1; /* str is longer */
10812+
return 0;
10813+
}
1080010814
kind = PyUnicode_KIND(uni);
1080110815
if (kind == PyUnicode_1BYTE_KIND) {
1080210816
const void *data = PyUnicode_1BYTE_DATA(uni);

0 commit comments

Comments
 (0)