Skip to content

Commit 2d72493

Browse files
authored
gh-129813, PEP 782: Use PyBytesWriter in _PyBytes_FormatEx() (#138839)
Replace the private _PyBytesWriter API with the new public PyBytesWriter API.
1 parent f01181b commit 2d72493

File tree

3 files changed

+36
-43
lines changed

3 files changed

+36
-43
lines changed

Include/internal/pycore_long.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ extern int _PyLong_FormatWriter(
135135
int alternate);
136136

137137
extern char* _PyLong_FormatBytesWriter(
138-
_PyBytesWriter *writer,
138+
PyBytesWriter *writer,
139139
char *str,
140140
PyObject *obj,
141141
int base,

Objects/bytesobject.c

Lines changed: 19 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ getnextarg(PyObject *args, Py_ssize_t arglen, Py_ssize_t *p_argidx)
432432

433433
static char*
434434
formatfloat(PyObject *v, int flags, int prec, int type,
435-
PyObject **p_result, _PyBytesWriter *writer, char *str)
435+
PyObject **p_result, PyBytesWriter *writer, char *str)
436436
{
437437
char *p;
438438
PyObject *result;
@@ -460,7 +460,7 @@ formatfloat(PyObject *v, int flags, int prec, int type,
460460

461461
len = strlen(p);
462462
if (writer != NULL) {
463-
str = _PyBytesWriter_Prepare(writer, str, len);
463+
str = PyBytesWriter_GrowAndUpdatePointer(writer, len, str);
464464
if (str == NULL) {
465465
PyMem_Free(p);
466466
return NULL;
@@ -611,12 +611,10 @@ _PyBytes_FormatEx(const char *format, Py_ssize_t format_len,
611611
PyObject *args, int use_bytearray)
612612
{
613613
const char *fmt;
614-
char *res;
615614
Py_ssize_t arglen, argidx;
616615
Py_ssize_t fmtcnt;
617616
int args_owned = 0;
618617
PyObject *dict = NULL;
619-
_PyBytesWriter writer;
620618

621619
if (args == NULL) {
622620
PyErr_BadInternalCall();
@@ -625,14 +623,17 @@ _PyBytes_FormatEx(const char *format, Py_ssize_t format_len,
625623
fmt = format;
626624
fmtcnt = format_len;
627625

628-
_PyBytesWriter_Init(&writer);
629-
writer.use_bytearray = use_bytearray;
630-
631-
res = _PyBytesWriter_Alloc(&writer, fmtcnt);
632-
if (res == NULL)
626+
PyBytesWriter *writer;
627+
if (use_bytearray) {
628+
writer = _PyBytesWriter_CreateByteArray(fmtcnt);
629+
}
630+
else {
631+
writer = PyBytesWriter_Create(fmtcnt);
632+
}
633+
if (writer == NULL) {
633634
return NULL;
634-
if (!use_bytearray)
635-
writer.overallocate = 1;
635+
}
636+
char *res = PyBytesWriter_GetData(writer);
636637

637638
if (PyTuple_Check(args)) {
638639
arglen = PyTuple_GET_SIZE(args);
@@ -835,11 +836,6 @@ _PyBytes_FormatEx(const char *format, Py_ssize_t format_len,
835836
if (v == NULL)
836837
goto error;
837838

838-
if (fmtcnt == 0) {
839-
/* last write: disable writer overallocation */
840-
writer.overallocate = 0;
841-
}
842-
843839
sign = 0;
844840
fill = ' ';
845841
switch (c) {
@@ -900,8 +896,7 @@ _PyBytes_FormatEx(const char *format, Py_ssize_t format_len,
900896
}
901897

902898
/* Fast path */
903-
writer.min_size -= 2; /* size preallocated for "%d" */
904-
res = _PyLong_FormatBytesWriter(&writer, res,
899+
res = _PyLong_FormatBytesWriter(writer, res,
905900
v, base, alternate);
906901
if (res == NULL)
907902
goto error;
@@ -929,8 +924,7 @@ _PyBytes_FormatEx(const char *format, Py_ssize_t format_len,
929924
&& !(flags & (F_SIGN | F_BLANK)))
930925
{
931926
/* Fast path */
932-
writer.min_size -= 2; /* size preallocated for "%f" */
933-
res = formatfloat(v, flags, prec, c, NULL, &writer, res);
927+
res = formatfloat(v, flags, prec, c, NULL, writer, res);
934928
if (res == NULL)
935929
goto error;
936930
continue;
@@ -986,9 +980,10 @@ _PyBytes_FormatEx(const char *format, Py_ssize_t format_len,
986980
alloc++;
987981
/* 2: size preallocated for %s */
988982
if (alloc > 2) {
989-
res = _PyBytesWriter_Prepare(&writer, res, alloc - 2);
990-
if (res == NULL)
983+
res = PyBytesWriter_GrowAndUpdatePointer(writer, alloc - 2, res);
984+
if (res == NULL) {
991985
goto error;
986+
}
992987
}
993988
#ifndef NDEBUG
994989
char *before = res;
@@ -1061,10 +1056,6 @@ _PyBytes_FormatEx(const char *format, Py_ssize_t format_len,
10611056
assert((res - before) == alloc);
10621057
#endif
10631058
} /* '%' */
1064-
1065-
/* If overallocation was disabled, ensure that it was the last
1066-
write. Otherwise, we missed an optimization */
1067-
assert(writer.overallocate || fmtcnt == 0 || use_bytearray);
10681059
} /* until end */
10691060

10701061
if (argidx < arglen && !dict) {
@@ -1076,10 +1067,10 @@ _PyBytes_FormatEx(const char *format, Py_ssize_t format_len,
10761067
if (args_owned) {
10771068
Py_DECREF(args);
10781069
}
1079-
return _PyBytesWriter_Finish(&writer, res);
1070+
return PyBytesWriter_FinishWithPointer(writer, res);
10801071

10811072
error:
1082-
_PyBytesWriter_Dealloc(&writer);
1073+
PyBytesWriter_Discard(writer);
10831074
if (args_owned) {
10841075
Py_DECREF(args);
10851076
}

Objects/longobject.c

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2020,7 +2020,7 @@ static int
20202020
pylong_int_to_decimal_string(PyObject *aa,
20212021
PyObject **p_output,
20222022
_PyUnicodeWriter *writer,
2023-
_PyBytesWriter *bytes_writer,
2023+
PyBytesWriter *bytes_writer,
20242024
char **bytes_str)
20252025
{
20262026
PyObject *s = NULL;
@@ -2051,7 +2051,8 @@ pylong_int_to_decimal_string(PyObject *aa,
20512051
Py_ssize_t size = PyUnicode_GET_LENGTH(s);
20522052
const void *data = PyUnicode_DATA(s);
20532053
int kind = PyUnicode_KIND(s);
2054-
*bytes_str = _PyBytesWriter_Prepare(bytes_writer, *bytes_str, size);
2054+
*bytes_str = PyBytesWriter_GrowAndUpdatePointer(bytes_writer, size,
2055+
*bytes_str);
20552056
if (*bytes_str == NULL) {
20562057
goto error;
20572058
}
@@ -2088,7 +2089,7 @@ static int
20882089
long_to_decimal_string_internal(PyObject *aa,
20892090
PyObject **p_output,
20902091
_PyUnicodeWriter *writer,
2091-
_PyBytesWriter *bytes_writer,
2092+
PyBytesWriter *bytes_writer,
20922093
char **bytes_str)
20932094
{
20942095
PyLongObject *scratch, *a;
@@ -2214,7 +2215,8 @@ long_to_decimal_string_internal(PyObject *aa,
22142215
}
22152216
}
22162217
else if (bytes_writer) {
2217-
*bytes_str = _PyBytesWriter_Prepare(bytes_writer, *bytes_str, strlen);
2218+
*bytes_str = PyBytesWriter_GrowAndUpdatePointer(bytes_writer, strlen,
2219+
*bytes_str);
22182220
if (*bytes_str == NULL) {
22192221
Py_DECREF(scratch);
22202222
return -1;
@@ -2324,7 +2326,7 @@ long_to_decimal_string(PyObject *aa)
23242326
static int
23252327
long_format_binary(PyObject *aa, int base, int alternate,
23262328
PyObject **p_output, _PyUnicodeWriter *writer,
2327-
_PyBytesWriter *bytes_writer, char **bytes_str)
2329+
PyBytesWriter *bytes_writer, char **bytes_str)
23282330
{
23292331
PyLongObject *a = (PyLongObject *)aa;
23302332
PyObject *v = NULL;
@@ -2385,7 +2387,8 @@ long_format_binary(PyObject *aa, int base, int alternate,
23852387
return -1;
23862388
}
23872389
else if (bytes_writer) {
2388-
*bytes_str = _PyBytesWriter_Prepare(bytes_writer, *bytes_str, sz);
2390+
*bytes_str = PyBytesWriter_GrowAndUpdatePointer(bytes_writer, sz,
2391+
*bytes_str);
23892392
if (*bytes_str == NULL)
23902393
return -1;
23912394
}
@@ -2514,7 +2517,7 @@ _PyLong_FormatWriter(_PyUnicodeWriter *writer,
25142517
}
25152518

25162519
char*
2517-
_PyLong_FormatBytesWriter(_PyBytesWriter *writer, char *str,
2520+
_PyLong_FormatBytesWriter(PyBytesWriter *writer, char *str,
25182521
PyObject *obj,
25192522
int base, int alternate)
25202523
{
@@ -6403,8 +6406,6 @@ int_to_bytes_impl(PyObject *self, Py_ssize_t length, PyObject *byteorder,
64036406
/*[clinic end generated code: output=89c801df114050a3 input=66f9d0c20529b44f]*/
64046407
{
64056408
int little_endian;
6406-
PyObject *bytes;
6407-
64086409
if (byteorder == NULL)
64096410
little_endian = 0;
64106411
else if (_PyUnicode_Equal(byteorder, &_Py_ID(little)))
@@ -6417,18 +6418,19 @@ int_to_bytes_impl(PyObject *self, Py_ssize_t length, PyObject *byteorder,
64176418
return NULL;
64186419
}
64196420

6420-
bytes = PyBytes_FromStringAndSize(NULL, length);
6421-
if (bytes == NULL)
6421+
PyBytesWriter *writer = PyBytesWriter_Create(length);
6422+
if (writer == NULL) {
64226423
return NULL;
6424+
}
64236425

64246426
if (_PyLong_AsByteArray((PyLongObject *)self,
6425-
(unsigned char *)PyBytes_AS_STRING(bytes),
6427+
PyBytesWriter_GetData(writer),
64266428
length, little_endian, is_signed, 1) < 0) {
6427-
Py_DECREF(bytes);
6429+
PyBytesWriter_Discard(writer);
64286430
return NULL;
64296431
}
64306432

6431-
return bytes;
6433+
return PyBytesWriter_Finish(writer);
64326434
}
64336435

64346436
/*[clinic input]

0 commit comments

Comments
 (0)