From abc0f29fb9b245efa3d12ba1e6b35c104f1784f1 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 9 Oct 2024 10:47:33 +0200 Subject: [PATCH] Add PyUnicode_Equal() function (#110) --- docs/api.rst | 4 ++++ docs/changelog.rst | 1 + pythoncapi_compat.h | 32 +++++++++++++++++++++++++++++ tests/test_pythoncapi_compat_cext.c | 7 +++++++ 4 files changed, 44 insertions(+) diff --git a/docs/api.rst b/docs/api.rst index 9063cc5..72d78e9 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -33,6 +33,10 @@ Python 3.14 See `PyLong_GetSign() documentation `__. +.. c:function:: int PyUnicode_Equal(PyObject *str1, PyObject *str2) + + See `PyUnicode_Equal() documentation `__. + .. c:function:: PyUnicodeWriter* PyUnicodeWriter_Create(Py_ssize_t length) See `PyUnicodeWriter_Create() documentation `__. diff --git a/docs/changelog.rst b/docs/changelog.rst index 1e7ba2a..5416a3d 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -1,6 +1,7 @@ Changelog ========= +* 2024-10-09: Add ``PyUnicode_Equal()`` function. * 2024-07-18: Add functions: * ``PyUnicodeWriter_Create()`` diff --git a/pythoncapi_compat.h b/pythoncapi_compat.h index c0feaa2..014d4cc 100644 --- a/pythoncapi_compat.h +++ b/pythoncapi_compat.h @@ -1514,6 +1514,38 @@ static inline int PyLong_GetSign(PyObject *obj, int *sign) #endif +// gh-124502 added PyUnicode_Equal() to Python 3.14.0a0 +#if PY_VERSION_HEX < 0x030E00A0 +static inline int PyUnicode_Equal(PyObject *str1, PyObject *str2) +{ + if (!PyUnicode_Check(str1)) { + PyErr_Format(PyExc_TypeError, + "first argument must be str, not %s", + Py_TYPE(str1)->tp_name); + return -1; + } + if (!PyUnicode_Check(str2)) { + PyErr_Format(PyExc_TypeError, + "second argument must be str, not %s", + Py_TYPE(str2)->tp_name); + return -1; + } + +#if PY_VERSION_HEX >= 0x030d0000 && !defined(PYPY_VERSION) + extern int _PyUnicode_Equal(PyObject *str1, PyObject *str2); + + return _PyUnicode_Equal(str1, str2); +#elif PY_VERSION_HEX >= 0x03060000 && !defined(PYPY_VERSION) + return _PyUnicode_EQ(str1, str2); +#elif PY_VERSION_HEX >= 0x03090000 && defined(PYPY_VERSION) + return _PyUnicode_EQ(str1, str2); +#else + return (PyUnicode_Compare(str1, str2) == 0); +#endif +} +#endif + + #ifdef __cplusplus } #endif diff --git a/tests/test_pythoncapi_compat_cext.c b/tests/test_pythoncapi_compat_cext.c index 5cf0f45..a2b07ed 100644 --- a/tests/test_pythoncapi_compat_cext.c +++ b/tests/test_pythoncapi_compat_cext.c @@ -1531,6 +1531,13 @@ test_unicode(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args)) assert(PyErr_ExceptionMatches(PyExc_MemoryError)); PyErr_Clear(); + // Test PyUnicode_Equal() + assert(PyUnicode_Equal(abc, abc) == 1); + assert(PyUnicode_Equal(abc, abc0def) == 0); + assert(PyUnicode_Equal(abc, Py_True) == -1); + assert(PyErr_ExceptionMatches(PyExc_TypeError)); + PyErr_Clear(); + Py_DECREF(abc); Py_DECREF(abc0def); Py_RETURN_NONE;