]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-89653: PEP 670: Fix PyUnicode_READ() cast (#92872)
authorVictor Stinner <vstinner@python.org>
Tue, 17 May 2022 17:20:37 +0000 (19:20 +0200)
committerGitHub <noreply@github.com>
Tue, 17 May 2022 17:20:37 +0000 (19:20 +0200)
_Py_CAST() cannot be used with a constant type: use _Py_STATIC_CAST()
instead.

Include/cpython/unicodeobject.h
Lib/test/_testcppext.cpp

index 274339d7f9fe6915948edfd78400e74fb28b79d4..f853b69dec9d1ad6a32f8a5d2bd56942bc8c347d 100644 (file)
@@ -340,7 +340,8 @@ static inline Py_UCS4 PyUnicode_READ(int kind,
 }
 #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
 #define PyUnicode_READ(kind, data, index) \
-    PyUnicode_READ(_Py_STATIC_CAST(int, kind), _Py_CAST(const void*, data), \
+    PyUnicode_READ(_Py_STATIC_CAST(int, kind), \
+                   _Py_STATIC_CAST(const void*, data), \
                    (index))
 #endif
 
index dc40f0ee9eb1cb953aabdfabb8449cf0ffc7f825..f38b4870e0edbc10aa78190858aebf85452a62cc 100644 (file)
@@ -50,9 +50,40 @@ test_api_casts(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
 }
 
 
+static PyObject *
+test_unicode(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
+{
+    PyObject *str = PyUnicode_FromString("abc");
+    if (str == nullptr) {
+        return nullptr;
+    }
+
+    assert(PyUnicode_Check(str));
+    assert(PyUnicode_GET_LENGTH(str) == 3);
+
+    // gh-92800: test PyUnicode_READ()
+    const void* data = PyUnicode_DATA(str);
+    assert(data != nullptr);
+    int kind = PyUnicode_KIND(str);
+    assert(kind == PyUnicode_1BYTE_KIND);
+    assert(PyUnicode_READ(kind, data, 0) == 'a');
+
+    // gh-92800: test PyUnicode_READ() casts
+    const void* const_data = PyUnicode_DATA(str);
+    unsigned int ukind = static_cast<unsigned int>(kind);
+    assert(PyUnicode_READ(ukind, const_data, 2) == 'c');
+
+    assert(PyUnicode_READ_CHAR(str, 1) == 'b');
+
+    Py_DECREF(str);
+    Py_RETURN_NONE;
+}
+
+
 static PyMethodDef _testcppext_methods[] = {
     {"add", _testcppext_add, METH_VARARGS, _testcppext_add_doc},
     {"test_api_casts", test_api_casts, METH_NOARGS, nullptr},
+    {"test_unicode", test_unicode, METH_NOARGS, nullptr},
     {nullptr, nullptr, 0, nullptr}  /* sentinel */
 };