Skip to content

Commit cdf0abe

Browse files
authored
Add PyUnicodeWriter_WriteUCS4() function (#194)
1 parent 3d365fe commit cdf0abe

4 files changed

Lines changed: 35 additions & 5 deletions

File tree

‎docs/api.rst‎

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
pythoncapi_compat.h API
33
+++++++++++++++++++++++
44

5-
The ``pythoncapi_compat.h`` header file provides implementations of recent
6-
functions for old Python versions.
5+
The ``pythoncapi_compat.h`` header file provides implementations of around 150
6+
recent functions for old Python versions.
77

88
Supported Python versions:
99

10-
* Python 3.6 - 3.15
10+
* Python 3.6 - 3.16
1111
* PyPy 3.6 - 3.12
1212

1313
C++03 and C++11 are supported on Python 3.6 and newer.
@@ -193,6 +193,12 @@ Python 3.14
193193

194194
Not available on the limited C API.
195195

196+
.. c:function:: int PyUnicodeWriter_WriteUCS4(PyUnicodeWriter *writer, const Py_UCS4 *ucs4, Py_ssize_t size)
197+
198+
See `PyUnicodeWriter_WriteUCS4() documentation <https://docs.python.org/dev/c-api/unicode.html#c.PyUnicodeWriter_WriteUCS4>`__.
199+
200+
Not available on the limited C API.
201+
196202
.. c:function:: int PyUnicodeWriter_WriteUTF8(PyUnicodeWriter *writer, const char *str, Py_ssize_t size)
197203

198204
See `PyUnicodeWriter_WriteUTF8() documentation <https://docs.python.org/dev/c-api/unicode.html#c.PyUnicodeWriter_WriteUTF8>`__.
@@ -338,7 +344,6 @@ Not supported:
338344
* ``PyInitConfig_SetStrList()``
339345
* ``PyType_GetBaseByToken()``
340346
* ``PyUnicodeWriter_DecodeUTF8Stateful()``
341-
* ``PyUnicodeWriter_WriteUCS4()``
342347
* ``Py_InitializeFromInitConfig()``
343348

344349

‎docs/changelog.rst‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
Changelog
22
=========
33

4+
* 2026-10-10: Add ``PyUnicodeWriter_WriteUCS4()`` function.
45
* 2026-10-08: Add support for the limited C API 3.2.
56
* 2026-10-08: Add functions:
67

‎pythoncapi_compat.h‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1645,6 +1645,21 @@ PyUnicodeWriter_WriteSubstring(PyUnicodeWriter *writer, PyObject *str,
16451645
start, end);
16461646
}
16471647

1648+
static inline int
1649+
PyUnicodeWriter_WriteUCS4(PyUnicodeWriter *writer,
1650+
const Py_UCS4 *ucs4, Py_ssize_t size)
1651+
{
1652+
PyObject *str = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND,
1653+
ucs4, size);
1654+
if (str == NULL) {
1655+
return -1;
1656+
}
1657+
1658+
int res = _PyUnicodeWriter_WriteStr((_PyUnicodeWriter*)writer, str);
1659+
Py_DECREF(str);
1660+
return res;
1661+
}
1662+
16481663
static inline int
16491664
PyUnicodeWriter_Format(PyUnicodeWriter *writer, const char *format, ...)
16501665
{

‎tests/test_pythoncapi_compat_cext.c‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1899,6 +1899,7 @@ test_unicodewriter(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(args))
18991899
return NULL;
19001900
}
19011901
int ret;
1902+
const Py_UCS4 ucs4[] = {'u', 'c', 's', '4'};
19021903

19031904
// test PyUnicodeWriter_WriteStr()
19041905
PyObject *str = PyUnicode_FromString("var");
@@ -1940,6 +1941,14 @@ test_unicodewriter(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(args))
19401941
goto error;
19411942
}
19421943

1944+
// test PyUnicodeWriter_WriteUCS4()
1945+
if (PyUnicodeWriter_WriteUCS4(writer, ucs4, Py_ARRAY_LENGTH(ucs4)) < 0) {
1946+
goto error;
1947+
}
1948+
if (PyUnicodeWriter_WriteChar(writer, ' ') < 0) {
1949+
goto error;
1950+
}
1951+
19431952
// test PyUnicodeWriter_WriteRepr()
19441953
str = PyUnicode_FromString("repr");
19451954
if (str == NULL) {
@@ -1958,7 +1967,7 @@ test_unicodewriter(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(args))
19581967
if (result == NULL) {
19591968
return NULL;
19601969
}
1961-
const char *expected = "var=long non-ASCII valu\xC3\xA9 'repr'<NULL>";
1970+
const char *expected = "var=long non-ASCII valu\xC3\xA9 ucs4 'repr'<NULL>";
19621971
assert(PyUnicode_EqualToUTF8(result, expected));
19631972
Py_DECREF(result);
19641973
}

0 commit comments

Comments
 (0)