Skip to content

Commit b301c29

Browse files
authored
gh-161172: Add PyUnicodeWriter to the limited C API (#161175)
Keep tests in _testcapi to access the deprecated function _PyUnicodeWriter_WriteLatin1String() which is excluded from the limited C API.
1 parent 6fa6d09 commit b301c29

10 files changed

Lines changed: 134 additions & 61 deletions

File tree

‎Doc/c-api/unicode.rst‎

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1697,10 +1697,12 @@ They all return ``NULL`` or ``-1`` if an exception occurs.
16971697
intern-related details, may change between CPython versions.
16981698
16991699
1700+
.. _pyunicodewriter:
1701+
17001702
PyUnicodeWriter
17011703
^^^^^^^^^^^^^^^
17021704
1703-
The :c:type:`PyUnicodeWriter` API can be used to create a Python :class:`str`
1705+
The ``PyUnicodeWriter`` API can be used to create a Python :class:`str`
17041706
object.
17051707
17061708
.. versionadded:: 3.14
@@ -1916,7 +1918,7 @@ then filling in its contents.
19161918
They are :term:`soft deprecated`: they break the assumption that
19171919
strings are immutable, making them hard to use correctly.
19181920
1919-
Prefer using the :c:type:`PyUnicodeWriter` API,
1921+
Prefer using the :ref:`PyUnicodeWriter API <pyunicodewriter>`,
19201922
or one of the ``PyUnicode_From*``
19211923
functions such as :c:func:`PyUnicode_FromStringAndSize`.
19221924
@@ -1971,7 +1973,7 @@ Python does not always check these requirements.
19711973
.. versionadded:: 3.3
19721974
19731975
.. soft-deprecated:: 3.16
1974-
Use the :c:type:`PyUnicodeWriter` API instead.
1976+
Use the :ref:`PyUnicodeWriter API <pyunicodewriter>` instead.
19751977
19761978
19771979
.. c:function:: Py_ssize_t PyUnicode_CopyCharacters(PyObject *to, \
@@ -1991,7 +1993,7 @@ Python does not always check these requirements.
19911993
.. versionadded:: 3.3
19921994
19931995
.. soft-deprecated:: 3.16
1994-
Use the :c:type:`PyUnicodeWriter` API instead.
1996+
Use the :ref:`PyUnicodeWriter API <pyunicodewriter>` instead.
19951997
19961998
19971999
.. c:function:: int PyUnicode_Resize(PyObject **unicode, Py_ssize_t length);
@@ -2012,7 +2014,7 @@ Python does not always check these requirements.
20122014
See :ref:`pyunicode-new-mutating` for details.
20132015
20142016
.. soft-deprecated:: 3.16
2015-
Use the :c:type:`PyUnicodeWriter` API instead.
2017+
Use the :ref:`PyUnicodeWriter API <pyunicodewriter>` instead.
20162018
20172019
20182020
.. c:function:: Py_ssize_t PyUnicode_Fill(PyObject *unicode, Py_ssize_t start, \
@@ -2033,7 +2035,7 @@ Python does not always check these requirements.
20332035
.. versionadded:: 3.3
20342036
20352037
.. soft-deprecated:: 3.16
2036-
Use the :c:type:`PyUnicodeWriter` API instead.
2038+
Use the :ref:`PyUnicodeWriter API <pyunicodewriter>` instead.
20372039
20382040
20392041
.. c:function:: int PyUnicode_WriteChar(PyObject *unicode, Py_ssize_t index, \
@@ -2053,4 +2055,4 @@ Python does not always check these requirements.
20532055
.. versionadded:: 3.3
20542056
20552057
.. soft-deprecated:: 3.16
2056-
Use the :c:type:`PyUnicodeWriter` API instead.
2058+
Use the :ref:`PyUnicodeWriter API <pyunicodewriter>` instead.

‎Doc/data/stable_abi.dat‎

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Doc/whatsnew/3.14.rst‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2990,7 +2990,7 @@ New features in the C API
29902990
The function is also added to the Limited C API.
29912991
(Contributed by Victor Stinner in :gh:`124502`.)
29922992

2993-
* Add a new :c:type:`PyUnicodeWriter` API to create a Python :class:`str`
2993+
* Add a new :ref:`PyUnicodeWriter API <pyunicodewriter>` to create a Python :class:`str`
29942994
object, with the following functions:
29952995

29962996
* :c:func:`PyUnicodeWriter_Create`

‎Doc/whatsnew/3.16.rst‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1387,6 +1387,9 @@ New features
13871387
API.
13881388
(Contributed by Nathan Goldbaum and Victor Stinner in :gh:`158842`.)
13891389

1390+
* Add the :ref:`PyUnicodeWriter API <pyunicodewriter>` to the limited C API.
1391+
(Contributed by Victor Stinner in :gh:`161172`.)
1392+
13901393
Porting to Python 3.16
13911394
----------------------
13921395

@@ -1434,7 +1437,7 @@ Deprecated C APIs
14341437
:c:func:`PyUnicode_New`, :c:func:`PyUnicode_CopyCharacters`,
14351438
:c:func:`PyUnicode_Fill`, :c:func:`PyUnicode_Resize`,
14361439
:c:func:`PyUnicode_WRITE` and :c:func:`PyUnicode_WriteChar`.
1437-
Use the safer :c:type:`PyUnicodeWriter` API instead.
1440+
Use the safer :ref:`PyUnicodeWriter API <pyunicodewriter>` instead.
14381441
(Contributed by Victor Stinner in :gh:`157710`.)
14391442

14401443
.. Add C API deprecations above alphabetically, not here at the end.

‎Include/cpython/unicodeobject.h‎

Lines changed: 0 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -471,57 +471,6 @@ PyAPI_FUNC(PyObject*) PyUnicode_FromKindAndData(
471471
Py_ssize_t size);
472472

473473

474-
/* --- Public PyUnicodeWriter API ----------------------------------------- */
475-
476-
typedef struct PyUnicodeWriter PyUnicodeWriter;
477-
478-
PyAPI_FUNC(PyUnicodeWriter*) PyUnicodeWriter_Create(Py_ssize_t length);
479-
PyAPI_FUNC(void) PyUnicodeWriter_Discard(PyUnicodeWriter *writer);
480-
PyAPI_FUNC(PyObject*) PyUnicodeWriter_Finish(PyUnicodeWriter *writer);
481-
482-
PyAPI_FUNC(int) PyUnicodeWriter_WriteChar(
483-
PyUnicodeWriter *writer,
484-
Py_UCS4 ch);
485-
PyAPI_FUNC(int) PyUnicodeWriter_WriteUTF8(
486-
PyUnicodeWriter *writer,
487-
const char *str,
488-
Py_ssize_t size);
489-
PyAPI_FUNC(int) PyUnicodeWriter_WriteASCII(
490-
PyUnicodeWriter *writer,
491-
const char *str,
492-
Py_ssize_t size);
493-
PyAPI_FUNC(int) PyUnicodeWriter_WriteWideChar(
494-
PyUnicodeWriter *writer,
495-
const wchar_t *str,
496-
Py_ssize_t size);
497-
PyAPI_FUNC(int) PyUnicodeWriter_WriteUCS4(
498-
PyUnicodeWriter *writer,
499-
const Py_UCS4 *str,
500-
Py_ssize_t size);
501-
502-
PyAPI_FUNC(int) PyUnicodeWriter_WriteStr(
503-
PyUnicodeWriter *writer,
504-
PyObject *obj);
505-
PyAPI_FUNC(int) PyUnicodeWriter_WriteRepr(
506-
PyUnicodeWriter *writer,
507-
PyObject *obj);
508-
PyAPI_FUNC(int) PyUnicodeWriter_WriteSubstring(
509-
PyUnicodeWriter *writer,
510-
PyObject *str,
511-
Py_ssize_t start,
512-
Py_ssize_t end);
513-
PyAPI_FUNC(int) PyUnicodeWriter_Format(
514-
PyUnicodeWriter *writer,
515-
const char *format,
516-
...);
517-
PyAPI_FUNC(int) PyUnicodeWriter_DecodeUTF8Stateful(
518-
PyUnicodeWriter *writer,
519-
const char *str, /* UTF-8 encoded string */
520-
Py_ssize_t size, /* size of string */
521-
const char *errors, /* error handling */
522-
Py_ssize_t *consumed); /* bytes consumed */
523-
524-
525474
/* --- Private _PyUnicodeWriter API --------------------------------------- */
526475

527476
typedef struct {

‎Include/unicodeobject.h‎

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -954,7 +954,59 @@ PyAPI_FUNC(int) PyUnicode_Contains(
954954

955955
PyAPI_FUNC(int) PyUnicode_IsIdentifier(PyObject *s);
956956

957-
/* === Characters Type APIs =============================================== */
957+
958+
/* === Public PyUnicodeWriter API ========================================= */
959+
960+
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= _Py_PACK_VERSION(3, 16)
961+
typedef struct PyUnicodeWriter PyUnicodeWriter;
962+
963+
PyAPI_FUNC(PyUnicodeWriter*) PyUnicodeWriter_Create(Py_ssize_t length);
964+
PyAPI_FUNC(void) PyUnicodeWriter_Discard(PyUnicodeWriter *writer);
965+
PyAPI_FUNC(PyObject*) PyUnicodeWriter_Finish(PyUnicodeWriter *writer);
966+
967+
PyAPI_FUNC(int) PyUnicodeWriter_WriteChar(
968+
PyUnicodeWriter *writer,
969+
Py_UCS4 ch);
970+
PyAPI_FUNC(int) PyUnicodeWriter_WriteUTF8(
971+
PyUnicodeWriter *writer,
972+
const char *str,
973+
Py_ssize_t size);
974+
PyAPI_FUNC(int) PyUnicodeWriter_WriteASCII(
975+
PyUnicodeWriter *writer,
976+
const char *str,
977+
Py_ssize_t size);
978+
PyAPI_FUNC(int) PyUnicodeWriter_WriteWideChar(
979+
PyUnicodeWriter *writer,
980+
const wchar_t *str,
981+
Py_ssize_t size);
982+
PyAPI_FUNC(int) PyUnicodeWriter_WriteUCS4(
983+
PyUnicodeWriter *writer,
984+
const Py_UCS4 *str,
985+
Py_ssize_t size);
986+
987+
PyAPI_FUNC(int) PyUnicodeWriter_WriteStr(
988+
PyUnicodeWriter *writer,
989+
PyObject *obj);
990+
PyAPI_FUNC(int) PyUnicodeWriter_WriteRepr(
991+
PyUnicodeWriter *writer,
992+
PyObject *obj);
993+
PyAPI_FUNC(int) PyUnicodeWriter_WriteSubstring(
994+
PyUnicodeWriter *writer,
995+
PyObject *str,
996+
Py_ssize_t start,
997+
Py_ssize_t end);
998+
PyAPI_FUNC(int) PyUnicodeWriter_Format(
999+
PyUnicodeWriter *writer,
1000+
const char *format,
1001+
...);
1002+
PyAPI_FUNC(int) PyUnicodeWriter_DecodeUTF8Stateful(
1003+
PyUnicodeWriter *writer,
1004+
const char *str, /* UTF-8 encoded string */
1005+
Py_ssize_t size, /* size of string */
1006+
const char *errors, /* error handling */
1007+
Py_ssize_t *consumed); /* bytes consumed */
1008+
#endif // !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= _Py_PACK_VERSION(3, 16)
1009+
9581010

9591011
#ifndef Py_LIMITED_API
9601012
# define Py_CPYTHON_UNICODEOBJECT_H

‎Lib/test/test_stable_abi_ctypes.py‎

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Add the :ref:`PyUnicodeWriter API <pyunicodewriter>` to the limited C API.
2+
Patch by Victor Stinner.

‎Misc/stable_abi.toml‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2915,3 +2915,29 @@
29152915
added = '3.16'
29162916
[macro.Py_XSETREF]
29172917
added = '3.16'
2918+
[function.PyUnicodeWriter_Create]
2919+
added = '3.16'
2920+
[function.PyUnicodeWriter_Discard]
2921+
added = '3.16'
2922+
[function.PyUnicodeWriter_Finish]
2923+
added = '3.16'
2924+
[function.PyUnicodeWriter_WriteChar]
2925+
added = '3.16'
2926+
[function.PyUnicodeWriter_WriteUTF8]
2927+
added = '3.16'
2928+
[function.PyUnicodeWriter_WriteASCII]
2929+
added = '3.16'
2930+
[function.PyUnicodeWriter_WriteWideChar]
2931+
added = '3.16'
2932+
[function.PyUnicodeWriter_WriteUCS4]
2933+
added = '3.16'
2934+
[function.PyUnicodeWriter_WriteStr]
2935+
added = '3.16'
2936+
[function.PyUnicodeWriter_WriteRepr]
2937+
added = '3.16'
2938+
[function.PyUnicodeWriter_WriteSubstring]
2939+
added = '3.16'
2940+
[function.PyUnicodeWriter_Format]
2941+
added = '3.16'
2942+
[function.PyUnicodeWriter_DecodeUTF8Stateful]
2943+
added = '3.16'

‎PC/python3dll.c‎

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)