summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorscoder <stefan_ml@behnel.de>2021-04-25 07:12:44 +0200
committerGitHub <noreply@github.com>2021-04-25 07:12:44 +0200
commit5f8c72dfa8ffb7c2a9b85552f65fc2f0fe85f2fe (patch)
treee5b6522a7f105137f33f773689b3796141bb6702
parent30f5ad30542c63156e4babcab1e783ef44b09e15 (diff)
downloadcython-5f8c72dfa8ffb7c2a9b85552f65fc2f0fe85f2fe.tar.gz
Make "__Pyx_UnicodeContainsUCS4()" work for WCHAR unicode strings with Py3.9+. (GH-4135)
* Use the same fallback as for missing PEP-393 support. * Prepare for "PyUnicode_READY()" and "PyUnicode_WCHAR_KIND" to be removed in Py3.12. See https://www.python.org/dev/peps/pep-0623/ * Avoid C compiler warnings about deprecated C-API functions in Py3.9+. Closes https://github.com/cython/cython/issues/3925
-rw-r--r--Cython/Utility/ModuleSetupCode.c13
-rw-r--r--Cython/Utility/ObjectHandling.c4
-rw-r--r--Cython/Utility/Optimize.c2
-rw-r--r--Cython/Utility/StringTools.c35
4 files changed, 42 insertions, 12 deletions
diff --git a/Cython/Utility/ModuleSetupCode.c b/Cython/Utility/ModuleSetupCode.c
index 3929bc64b..8119e083f 100644
--- a/Cython/Utility/ModuleSetupCode.c
+++ b/Cython/Utility/ModuleSetupCode.c
@@ -733,8 +733,15 @@ static CYTHON_INLINE PyObject * __Pyx_PyDict_GetItemStrWithError(PyObject *dict,
#elif PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
/* new Py3.3 unicode type (PEP 393) */
#define CYTHON_PEP393_ENABLED 1
+
+ #if defined(PyUnicode_IS_READY)
#define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ? \
0 : _PyUnicode_Ready((PyObject *)(op)))
+ #else
+ // Py3.12 / PEP-623 will remove wstr type unicode strings and all of the PyUnicode_READY() machinery.
+ #define __Pyx_PyUnicode_READY(op) (0)
+ #endif
+
#define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u)
#define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
#define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) PyUnicode_MAX_CHAR_VALUE(u)
@@ -743,7 +750,13 @@ static CYTHON_INLINE PyObject * __Pyx_PyDict_GetItemStrWithError(PyObject *dict,
#define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i)
#define __Pyx_PyUnicode_WRITE(k, d, i, ch) PyUnicode_WRITE(k, d, i, ch)
#if defined(PyUnicode_IS_READY) && defined(PyUnicode_GET_SIZE)
+ #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03090000
+ // Avoid calling deprecated C-API functions in Py3.9+ that PEP-623 schedules for removal in Py3.12.
+ // https://www.python.org/dev/peps/pep-0623/
+ #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : ((PyCompactUnicodeObject *)(u))->wstr_length))
+ #else
#define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u)))
+ #endif
#else
#define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_LENGTH(u))
#endif
diff --git a/Cython/Utility/ObjectHandling.c b/Cython/Utility/ObjectHandling.c
index 903c03833..10de79d61 100644
--- a/Cython/Utility/ObjectHandling.c
+++ b/Cython/Utility/ObjectHandling.c
@@ -2928,9 +2928,9 @@ static CYTHON_INLINE PyObject *__Pyx_PyUnicode_ConcatInPlaceImpl(PyObject **p_le
PyObject *left = *p_left;
Py_ssize_t left_len, right_len, new_len;
- if (unlikely(PyUnicode_READY(left) == -1))
+ if (unlikely(__Pyx_PyUnicode_READY(left) == -1))
return NULL;
- if (unlikely(PyUnicode_READY(right) == -1))
+ if (unlikely(__Pyx_PyUnicode_READY(right) == -1))
return NULL;
// Shortcuts
diff --git a/Cython/Utility/Optimize.c b/Cython/Utility/Optimize.c
index f9637b670..207c2d3ab 100644
--- a/Cython/Utility/Optimize.c
+++ b/Cython/Utility/Optimize.c
@@ -789,7 +789,7 @@ fallback:
static CYTHON_INLINE double __Pyx_PyUnicode_AsDouble(PyObject *obj) {
// Currently not optimised for Py2.7.
#if PY_MAJOR_VERSION >= 3 && !CYTHON_COMPILING_IN_PYPY
- if (unlikely(PyUnicode_READY(obj) == -1))
+ if (unlikely(__Pyx_PyUnicode_READY(obj) == -1))
return (double)-1;
if (likely(PyUnicode_IS_ASCII(obj))) {
const char *s;
diff --git a/Cython/Utility/StringTools.c b/Cython/Utility/StringTools.c
index feb6c99df..aa8c06d55 100644
--- a/Cython/Utility/StringTools.c
+++ b/Cython/Utility/StringTools.c
@@ -118,8 +118,19 @@ static CYTHON_INLINE int __Pyx_UnicodeContainsUCS4(PyObject* unicode, Py_UCS4 ch
//////////////////// PyUCS4InUnicode ////////////////////
+#if PY_VERSION_HEX < 0x03090000 || (defined(PyUnicode_WCHAR_KIND) && defined(PyUnicode_AS_UNICODE))
+
#if PY_VERSION_HEX < 0x03090000
-#if Py_UNICODE_SIZE == 2
+#define __Pyx_PyUnicode_AS_UNICODE(op) PyUnicode_AS_UNICODE(op)
+#define __Pyx_PyUnicode_GET_SIZE(op) PyUnicode_GET_SIZE(op)
+#else
+// Avoid calling deprecated C-API functions in Py3.9+ that PEP-623 schedules for removal in Py3.12.
+// https://www.python.org/dev/peps/pep-0623/
+#define __Pyx_PyUnicode_AS_UNICODE(op) (((PyASCIIObject *)(op))->wstr)
+#define __Pyx_PyUnicode_GET_SIZE(op) ((PyCompactUnicodeObject *)(op))->wstr_length
+#endif
+
+#if !defined(Py_UNICODE_SIZE) || Py_UNICODE_SIZE == 2
static int __Pyx_PyUnicodeBufferContainsUCS4_SP(Py_UNICODE* buffer, Py_ssize_t length, Py_UCS4 character) {
/* handle surrogate pairs for Py_UNICODE buffers in 16bit Unicode builds */
Py_UNICODE high_val, low_val;
@@ -147,7 +158,10 @@ static int __Pyx_PyUnicodeBufferContainsUCS4_BMP(Py_UNICODE* buffer, Py_ssize_t
static CYTHON_INLINE int __Pyx_UnicodeContainsUCS4(PyObject* unicode, Py_UCS4 character) {
#if CYTHON_PEP393_ENABLED
const int kind = PyUnicode_KIND(unicode);
- if (likely(kind != PyUnicode_WCHAR_KIND)) {
+ #ifdef PyUnicode_WCHAR_KIND
+ if (likely(kind != PyUnicode_WCHAR_KIND))
+ #endif
+ {
Py_ssize_t i;
const void* udata = PyUnicode_DATA(unicode);
const Py_ssize_t length = PyUnicode_GET_LENGTH(unicode);
@@ -158,20 +172,23 @@ static CYTHON_INLINE int __Pyx_UnicodeContainsUCS4(PyObject* unicode, Py_UCS4 ch
}
#elif PY_VERSION_HEX >= 0x03090000
#error Cannot use "UChar in Unicode" in Python 3.9 without PEP-393 unicode strings.
+#elif !defined(PyUnicode_AS_UNICODE)
+ #error Cannot use "UChar in Unicode" in Python < 3.9 without Py_UNICODE support.
#endif
-#if PY_VERSION_HEX < 0x03090000
-#if Py_UNICODE_SIZE == 2
- if (unlikely(character > 65535)) {
+
+#if PY_VERSION_HEX < 0x03090000 || (defined(PyUnicode_WCHAR_KIND) && defined(PyUnicode_AS_UNICODE))
+#if !defined(Py_UNICODE_SIZE) || Py_UNICODE_SIZE == 2
+ if ((sizeof(Py_UNICODE) == 2) && unlikely(character > 65535)) {
return __Pyx_PyUnicodeBufferContainsUCS4_SP(
- PyUnicode_AS_UNICODE(unicode),
- PyUnicode_GET_SIZE(unicode),
+ __Pyx_PyUnicode_AS_UNICODE(unicode),
+ __Pyx_PyUnicode_GET_SIZE(unicode),
character);
} else
#endif
{
return __Pyx_PyUnicodeBufferContainsUCS4_BMP(
- PyUnicode_AS_UNICODE(unicode),
- PyUnicode_GET_SIZE(unicode),
+ __Pyx_PyUnicode_AS_UNICODE(unicode),
+ __Pyx_PyUnicode_GET_SIZE(unicode),
character);
}