Skip to content

Commit 519c2c6

Browse files
authored
gh-128863: Deprecate the private _PyUnicodeWriter API (#129245)
Deprecate private C API functions: * _PyUnicodeWriter_Init() * _PyUnicodeWriter_Finish() * _PyUnicodeWriter_Dealloc() * _PyUnicodeWriter_WriteChar() * _PyUnicodeWriter_WriteStr() * _PyUnicodeWriter_WriteSubstring() * _PyUnicodeWriter_WriteASCIIString() * _PyUnicodeWriter_WriteLatin1String() These functions are not deprecated in the internal C API (if the Py_BUILD_CORE macro is defined).
1 parent 3bda821 commit 519c2c6

File tree

4 files changed

+130
-47
lines changed

4 files changed

+130
-47
lines changed

Doc/deprecations/c-api-pending-removal-in-3.18.rst

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,32 @@ Pending removal in Python 3.18
1111
use :c:func:`PyLongWriter_Create`.
1212
* :c:func:`!_PyThreadState_UncheckedGet`: use :c:func:`PyThreadState_GetUnchecked`.
1313
* :c:func:`!_PyUnicode_AsString`: use :c:func:`PyUnicode_AsUTF8`.
14+
* :c:func:`!_PyUnicodeWriter_Init`:
15+
replace ``_PyUnicodeWriter_Init(&writer)`` with
16+
:c:func:`writer = PyUnicodeWriter_Create(0) <PyUnicodeWriter_Create>`.
17+
* :c:func:`!_PyUnicodeWriter_Finish`:
18+
replace ``_PyUnicodeWriter_Finish(&writer)`` with
19+
:c:func:`PyUnicodeWriter_Finish(writer) <PyUnicodeWriter_Finish>`.
20+
* :c:func:`!_PyUnicodeWriter_Dealloc`:
21+
replace ``_PyUnicodeWriter_Dealloc(&writer)`` with
22+
:c:func:`PyUnicodeWriter_Discard(writer) <PyUnicodeWriter_Discard>`.
23+
* :c:func:`!_PyUnicodeWriter_WriteChar`:
24+
replace ``_PyUnicodeWriter_WriteChar(&writer, ch)`` with
25+
:c:func:`PyUnicodeWriter_WriteChar(writer, ch) <PyUnicodeWriter_WriteChar>`.
26+
* :c:func:`!_PyUnicodeWriter_WriteStr`:
27+
replace ``_PyUnicodeWriter_WriteStr(&writer, str)`` with
28+
:c:func:`PyUnicodeWriter_WriteStr(writer, str) <PyUnicodeWriter_WriteStr>`.
29+
* :c:func:`!_PyUnicodeWriter_WriteSubstring`:
30+
replace ``_PyUnicodeWriter_WriteSubstring(&writer, str, start, end)`` with
31+
:c:func:`PyUnicodeWriter_WriteSubstring(writer, str, start, end) <PyUnicodeWriter_WriteSubstring>`.
32+
* :c:func:`!_PyUnicodeWriter_WriteASCIIString`:
33+
replace ``_PyUnicodeWriter_WriteASCIIString(&writer, str)`` with
34+
:c:func:`PyUnicodeWriter_WriteUTF8(writer, str) <PyUnicodeWriter_WriteUTF8>`.
35+
* :c:func:`!_PyUnicodeWriter_WriteLatin1String`:
36+
replace ``_PyUnicodeWriter_WriteLatin1String(&writer, str)`` with
37+
:c:func:`PyUnicodeWriter_WriteUTF8(writer, str) <PyUnicodeWriter_WriteUTF8>`.
38+
* :c:func:`!_PyUnicodeWriter_Prepare`: (no replacement).
39+
* :c:func:`!_PyUnicodeWriter_PrepareKind`: (no replacement).
1440
* :c:func:`!_Py_HashPointer`: use :c:func:`Py_HashPointer`.
1541
* :c:func:`!_Py_fopen_obj`: use :c:func:`Py_fopen`.
1642

Doc/whatsnew/3.14.rst

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1497,21 +1497,23 @@ Porting to Python 3.14
14971497

14981498
* Private functions promoted to public C APIs:
14991499

1500-
* ``_PyBytes_Join()``: :c:func:`PyBytes_Join`;
1501-
* ``_PyLong_IsNegative()``: :c:func:`PyLong_IsNegative`;
1502-
* ``_PyLong_IsPositive()``: :c:func:`PyLong_IsPositive`;
1503-
* ``_PyLong_IsZero()``: :c:func:`PyLong_IsZero`;
1504-
* ``_PyLong_Sign()``: :c:func:`PyLong_GetSign`;
1505-
* ``_PyUnicodeWriter_Dealloc()``: :c:func:`PyUnicodeWriter_Discard`;
1506-
* ``_PyUnicodeWriter_Finish()``: :c:func:`PyUnicodeWriter_Finish`;
1507-
* ``_PyUnicodeWriter_Init()``: :c:func:`PyUnicodeWriter_Create`;
1508-
* ``_PyUnicodeWriter_WriteChar()``: :c:func:`PyUnicodeWriter_WriteChar`;
1509-
* ``_PyUnicodeWriter_WriteStr()``: :c:func:`PyUnicodeWriter_WriteStr`;
1510-
* ``_PyUnicodeWriter_WriteSubstring()``: :c:func:`PyUnicodeWriter_WriteSubstring`;
1511-
* ``_PyUnicode_EQ()``: :c:func:`PyUnicode_Equal`;
1512-
* ``_PyUnicode_Equal()``: :c:func:`PyUnicode_Equal`;
1513-
* ``_Py_GetConfig()``: :c:func:`PyConfig_Get` and :c:func:`PyConfig_GetInt`;
1514-
* ``_Py_HashBytes()``: :c:func:`Py_HashBuffer`;
1500+
* ``_PyBytes_Join()``: :c:func:`PyBytes_Join`.
1501+
* ``_PyLong_IsNegative()``: :c:func:`PyLong_IsNegative`.
1502+
* ``_PyLong_IsPositive()``: :c:func:`PyLong_IsPositive`.
1503+
* ``_PyLong_IsZero()``: :c:func:`PyLong_IsZero`.
1504+
* ``_PyLong_Sign()``: :c:func:`PyLong_GetSign`.
1505+
* ``_PyUnicodeWriter_Dealloc()``: :c:func:`PyUnicodeWriter_Discard`.
1506+
* ``_PyUnicodeWriter_Finish()``: :c:func:`PyUnicodeWriter_Finish`.
1507+
* ``_PyUnicodeWriter_Init()``: use :c:func:`PyUnicodeWriter_Create`.
1508+
* ``_PyUnicodeWriter_Prepare()``: (no replacement).
1509+
* ``_PyUnicodeWriter_PrepareKind()``: (no replacement).
1510+
* ``_PyUnicodeWriter_WriteChar()``: :c:func:`PyUnicodeWriter_WriteChar`.
1511+
* ``_PyUnicodeWriter_WriteStr()``: :c:func:`PyUnicodeWriter_WriteStr`.
1512+
* ``_PyUnicodeWriter_WriteSubstring()``: :c:func:`PyUnicodeWriter_WriteSubstring`.
1513+
* ``_PyUnicode_EQ()``: :c:func:`PyUnicode_Equal`.
1514+
* ``_PyUnicode_Equal()``: :c:func:`PyUnicode_Equal`.
1515+
* ``_Py_GetConfig()``: :c:func:`PyConfig_Get` and :c:func:`PyConfig_GetInt`.
1516+
* ``_Py_HashBytes()``: :c:func:`Py_HashBuffer`.
15151517
* ``_Py_fopen_obj()``: :c:func:`Py_fopen`.
15161518

15171519
The `pythoncapi-compat project`_ can be used to get most of these new
@@ -1556,6 +1558,30 @@ Deprecated
15561558
use :c:func:`PyLongWriter_Create`.
15571559
* :c:func:`!_PyThreadState_UncheckedGet`: use :c:func:`PyThreadState_GetUnchecked`.
15581560
* :c:func:`!_PyUnicode_AsString`: use :c:func:`PyUnicode_AsUTF8`.
1561+
* :c:func:`!_PyUnicodeWriter_Init`:
1562+
replace ``_PyUnicodeWriter_Init(&writer)`` with
1563+
:c:func:`writer = PyUnicodeWriter_Create(0) <PyUnicodeWriter_Create>`.
1564+
* :c:func:`!_PyUnicodeWriter_Finish`:
1565+
replace ``_PyUnicodeWriter_Finish(&writer)`` with
1566+
:c:func:`PyUnicodeWriter_Finish(writer) <PyUnicodeWriter_Finish>`.
1567+
* :c:func:`!_PyUnicodeWriter_Dealloc`:
1568+
replace ``_PyUnicodeWriter_Dealloc(&writer)`` with
1569+
:c:func:`PyUnicodeWriter_Discard(writer) <PyUnicodeWriter_Discard>`.
1570+
* :c:func:`!_PyUnicodeWriter_WriteChar`:
1571+
replace ``_PyUnicodeWriter_WriteChar(&writer, ch)`` with
1572+
:c:func:`PyUnicodeWriter_WriteChar(writer, ch) <PyUnicodeWriter_WriteChar>`.
1573+
* :c:func:`!_PyUnicodeWriter_WriteStr`:
1574+
replace ``_PyUnicodeWriter_WriteStr(&writer, str)`` with
1575+
:c:func:`PyUnicodeWriter_WriteStr(writer, str) <PyUnicodeWriter_WriteStr>`.
1576+
* :c:func:`!_PyUnicodeWriter_WriteSubstring`:
1577+
replace ``_PyUnicodeWriter_WriteSubstring(&writer, str, start, end)`` with
1578+
:c:func:`PyUnicodeWriter_WriteSubstring(writer, str, start, end) <PyUnicodeWriter_WriteSubstring>`.
1579+
* :c:func:`!_PyUnicodeWriter_WriteASCIIString`:
1580+
replace ``_PyUnicodeWriter_WriteASCIIString(&writer, str)`` with
1581+
:c:func:`PyUnicodeWriter_WriteUTF8(writer, str) <PyUnicodeWriter_WriteUTF8>`.
1582+
* :c:func:`!_PyUnicodeWriter_WriteLatin1String`:
1583+
replace ``_PyUnicodeWriter_WriteLatin1String(&writer, str)`` with
1584+
:c:func:`PyUnicodeWriter_WriteUTF8(writer, str) <PyUnicodeWriter_WriteUTF8>`.
15591585
* :c:func:`!_Py_HashPointer`: use :c:func:`Py_HashPointer`.
15601586
* :c:func:`!_Py_fopen_obj`: use :c:func:`Py_fopen`.
15611587

Include/cpython/unicodeobject.h

Lines changed: 28 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -530,8 +530,8 @@ typedef struct {
530530
// By default, the minimum buffer size is 0 character and overallocation is
531531
// disabled. Set min_length, min_char and overallocate attributes to control
532532
// the allocation of the buffer.
533-
PyAPI_FUNC(void)
534-
_PyUnicodeWriter_Init(_PyUnicodeWriter *writer);
533+
_Py_DEPRECATED_EXTERNALLY(3.14) PyAPI_FUNC(void) _PyUnicodeWriter_Init(
534+
_PyUnicodeWriter *writer);
535535

536536
/* Prepare the buffer to write 'length' characters
537537
with the specified maximum character.
@@ -547,9 +547,10 @@ _PyUnicodeWriter_Init(_PyUnicodeWriter *writer);
547547

548548
/* Don't call this function directly, use the _PyUnicodeWriter_Prepare() macro
549549
instead. */
550-
PyAPI_FUNC(int)
551-
_PyUnicodeWriter_PrepareInternal(_PyUnicodeWriter *writer,
552-
Py_ssize_t length, Py_UCS4 maxchar);
550+
_Py_DEPRECATED_EXTERNALLY(3.14) PyAPI_FUNC(int) _PyUnicodeWriter_PrepareInternal(
551+
_PyUnicodeWriter *writer,
552+
Py_ssize_t length,
553+
Py_UCS4 maxchar);
553554

554555
/* Prepare the buffer to have at least the kind KIND.
555556
For example, kind=PyUnicode_2BYTE_KIND ensures that the writer will
@@ -563,58 +564,53 @@ _PyUnicodeWriter_PrepareInternal(_PyUnicodeWriter *writer,
563564

564565
/* Don't call this function directly, use the _PyUnicodeWriter_PrepareKind()
565566
macro instead. */
566-
PyAPI_FUNC(int)
567-
_PyUnicodeWriter_PrepareKindInternal(_PyUnicodeWriter *writer,
568-
int kind);
567+
_Py_DEPRECATED_EXTERNALLY(3.14) PyAPI_FUNC(int) _PyUnicodeWriter_PrepareKindInternal(
568+
_PyUnicodeWriter *writer,
569+
int kind);
569570

570571
/* Append a Unicode character.
571572
Return 0 on success, raise an exception and return -1 on error. */
572-
PyAPI_FUNC(int)
573-
_PyUnicodeWriter_WriteChar(_PyUnicodeWriter *writer,
574-
Py_UCS4 ch
575-
);
573+
_Py_DEPRECATED_EXTERNALLY(3.14) PyAPI_FUNC(int) _PyUnicodeWriter_WriteChar(
574+
_PyUnicodeWriter *writer,
575+
Py_UCS4 ch);
576576

577577
/* Append a Unicode string.
578578
Return 0 on success, raise an exception and return -1 on error. */
579-
PyAPI_FUNC(int)
580-
_PyUnicodeWriter_WriteStr(_PyUnicodeWriter *writer,
581-
PyObject *str /* Unicode string */
582-
);
579+
_Py_DEPRECATED_EXTERNALLY(3.14) PyAPI_FUNC(int) _PyUnicodeWriter_WriteStr(
580+
_PyUnicodeWriter *writer,
581+
PyObject *str); /* Unicode string */
583582

584583
/* Append a substring of a Unicode string.
585584
Return 0 on success, raise an exception and return -1 on error. */
586-
PyAPI_FUNC(int)
587-
_PyUnicodeWriter_WriteSubstring(_PyUnicodeWriter *writer,
585+
_Py_DEPRECATED_EXTERNALLY(3.14) PyAPI_FUNC(int) _PyUnicodeWriter_WriteSubstring(
586+
_PyUnicodeWriter *writer,
588587
PyObject *str, /* Unicode string */
589588
Py_ssize_t start,
590-
Py_ssize_t end
591-
);
589+
Py_ssize_t end);
592590

593591
/* Append an ASCII-encoded byte string.
594592
Return 0 on success, raise an exception and return -1 on error. */
595-
PyAPI_FUNC(int)
596-
_PyUnicodeWriter_WriteASCIIString(_PyUnicodeWriter *writer,
593+
_Py_DEPRECATED_EXTERNALLY(3.14) PyAPI_FUNC(int) _PyUnicodeWriter_WriteASCIIString(
594+
_PyUnicodeWriter *writer,
597595
const char *str, /* ASCII-encoded byte string */
598-
Py_ssize_t len /* number of bytes, or -1 if unknown */
599-
);
596+
Py_ssize_t len); /* number of bytes, or -1 if unknown */
600597

601598
/* Append a latin1-encoded byte string.
602599
Return 0 on success, raise an exception and return -1 on error. */
603-
PyAPI_FUNC(int)
604-
_PyUnicodeWriter_WriteLatin1String(_PyUnicodeWriter *writer,
600+
_Py_DEPRECATED_EXTERNALLY(3.14) PyAPI_FUNC(int) _PyUnicodeWriter_WriteLatin1String(
601+
_PyUnicodeWriter *writer,
605602
const char *str, /* latin1-encoded byte string */
606-
Py_ssize_t len /* length in bytes */
607-
);
603+
Py_ssize_t len); /* length in bytes */
608604

609605
/* Get the value of the writer as a Unicode string. Clear the
610606
buffer of the writer. Raise an exception and return NULL
611607
on error. */
612-
PyAPI_FUNC(PyObject *)
613-
_PyUnicodeWriter_Finish(_PyUnicodeWriter *writer);
608+
_Py_DEPRECATED_EXTERNALLY(3.14) PyAPI_FUNC(PyObject *) _PyUnicodeWriter_Finish(
609+
_PyUnicodeWriter *writer);
614610

615611
/* Deallocate memory of a writer (clear its internal buffer). */
616-
PyAPI_FUNC(void)
617-
_PyUnicodeWriter_Dealloc(_PyUnicodeWriter *writer);
612+
_Py_DEPRECATED_EXTERNALLY(3.14) PyAPI_FUNC(void) _PyUnicodeWriter_Dealloc(
613+
_PyUnicodeWriter *writer);
618614

619615

620616
/* --- Manage the default encoding ---------------------------------------- */
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
The following private functions are deprecated and planned for removal in
2+
Python 3.18:
3+
4+
* :c:func:`!_PyUnicodeWriter_Init`:
5+
replace ``_PyUnicodeWriter_Init(&writer)`` with
6+
:c:func:`writer = PyUnicodeWriter_Create(0) <PyUnicodeWriter_Create>`.
7+
* :c:func:`!_PyUnicodeWriter_Finish`:
8+
replace ``_PyUnicodeWriter_Finish(&writer)`` with
9+
:c:func:`PyUnicodeWriter_Finish(writer) <PyUnicodeWriter_Finish>`.
10+
* :c:func:`!_PyUnicodeWriter_Dealloc`:
11+
replace ``_PyUnicodeWriter_Dealloc(&writer)`` with
12+
:c:func:`PyUnicodeWriter_Discard(writer) <PyUnicodeWriter_Discard>`.
13+
* :c:func:`!_PyUnicodeWriter_WriteChar`:
14+
replace ``_PyUnicodeWriter_WriteChar(&writer, ch)`` with
15+
:c:func:`PyUnicodeWriter_WriteChar(writer, ch) <PyUnicodeWriter_WriteChar>`.
16+
* :c:func:`!_PyUnicodeWriter_WriteStr`:
17+
replace ``_PyUnicodeWriter_WriteStr(&writer, str)`` with
18+
:c:func:`PyUnicodeWriter_WriteStr(writer, str) <PyUnicodeWriter_WriteStr>`.
19+
* :c:func:`!_PyUnicodeWriter_WriteSubstring`:
20+
replace ``_PyUnicodeWriter_WriteSubstring(&writer, str, start, end)`` with
21+
:c:func:`PyUnicodeWriter_WriteSubstring(writer, str, start, end) <PyUnicodeWriter_WriteSubstring>`.
22+
* :c:func:`!_PyUnicodeWriter_WriteASCIIString`:
23+
replace ``_PyUnicodeWriter_WriteASCIIString(&writer, str)`` with
24+
:c:func:`PyUnicodeWriter_WriteUTF8(writer, str) <PyUnicodeWriter_WriteUTF8>`.
25+
* :c:func:`!_PyUnicodeWriter_WriteLatin1String`:
26+
replace ``_PyUnicodeWriter_WriteLatin1String(&writer, str)`` with
27+
:c:func:`PyUnicodeWriter_WriteUTF8(writer, str) <PyUnicodeWriter_WriteUTF8>`.
28+
* :c:func:`!_PyUnicodeWriter_Prepare`: (no replacement).
29+
* :c:func:`!_PyUnicodeWriter_PrepareKind`: (no replacement).
30+
31+
The `pythoncapi-compat project
32+
<https://github.com/python/pythoncapi-compat/>`__ can be used to get these
33+
new public functions on Python 3.13 and older.
34+
35+
Patch by Victor Stinner.

0 commit comments

Comments
 (0)