Skip to content

Commit 430900d

Browse files
authored
gh-129813, PEP 782: Use PyBytesWriter in _PyBytes_FromList() (#138837)
Use the new public PyBytesWriter API in: * _PyBytes_FromHex() * _PyBytes_FromBuffer() * _PyBytes_FromList() * _PyBytes_FromTuple() * _PyBytes_FromIterator() Add _PyBytesWriter_ResizeAndUpdatePointer() and _PyBytesWriter_GetAllocated() helper functions.
1 parent af386fd commit 430900d

File tree

1 file changed

+78
-59
lines changed

1 file changed

+78
-59
lines changed

Objects/bytesobject.c

Lines changed: 78 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ class bytes "PyBytesObject *" "&PyBytes_Type"
3636
/* Forward declaration */
3737
Py_LOCAL_INLINE(Py_ssize_t) _PyBytesWriter_GetSize(_PyBytesWriter *writer,
3838
char *str);
39+
static void* _PyBytesWriter_ResizeAndUpdatePointer(PyBytesWriter *writer,
40+
Py_ssize_t size, void *data);
41+
static Py_ssize_t _PyBytesWriter_GetAllocated(PyBytesWriter *writer);
3942

4043

4144
#define CHARACTERS _Py_SINGLETON(bytes_characters)
@@ -2531,17 +2534,13 @@ bytes_fromhex_impl(PyTypeObject *type, PyObject *string)
25312534
PyObject*
25322535
_PyBytes_FromHex(PyObject *string, int use_bytearray)
25332536
{
2534-
char *buf;
25352537
Py_ssize_t hexlen, invalid_char;
25362538
unsigned int top, bot;
25372539
const Py_UCS1 *str, *start, *end;
2538-
_PyBytesWriter writer;
2540+
PyBytesWriter *writer = NULL;
25392541
Py_buffer view;
25402542
view.obj = NULL;
25412543

2542-
_PyBytesWriter_Init(&writer);
2543-
writer.use_bytearray = use_bytearray;
2544-
25452544
if (PyUnicode_Check(string)) {
25462545
hexlen = PyUnicode_GET_LENGTH(string);
25472546

@@ -2577,10 +2576,16 @@ _PyBytes_FromHex(PyObject *string, int use_bytearray)
25772576
}
25782577

25792578
/* This overestimates if there are spaces */
2580-
buf = _PyBytesWriter_Alloc(&writer, hexlen / 2);
2581-
if (buf == NULL) {
2579+
if (use_bytearray) {
2580+
writer = _PyBytesWriter_CreateByteArray(hexlen / 2);
2581+
}
2582+
else {
2583+
writer = PyBytesWriter_Create(hexlen / 2);
2584+
}
2585+
if (writer == NULL) {
25822586
goto release_buffer;
25832587
}
2588+
char *buf = PyBytesWriter_GetData(writer);
25842589

25852590
start = str;
25862591
end = str + hexlen;
@@ -2619,7 +2624,7 @@ _PyBytes_FromHex(PyObject *string, int use_bytearray)
26192624
if (view.obj != NULL) {
26202625
PyBuffer_Release(&view);
26212626
}
2622-
return _PyBytesWriter_Finish(&writer, buf);
2627+
return PyBytesWriter_FinishWithPointer(writer, buf);
26232628

26242629
error:
26252630
if (invalid_char == -1) {
@@ -2630,7 +2635,7 @@ _PyBytes_FromHex(PyObject *string, int use_bytearray)
26302635
"non-hexadecimal number found in "
26312636
"fromhex() arg at position %zd", invalid_char);
26322637
}
2633-
_PyBytesWriter_Dealloc(&writer);
2638+
PyBytesWriter_Discard(writer);
26342639

26352640
release_buffer:
26362641
if (view.obj != NULL) {
@@ -2857,47 +2862,44 @@ bytes_new_impl(PyTypeObject *type, PyObject *x, const char *encoding,
28572862
static PyObject*
28582863
_PyBytes_FromBuffer(PyObject *x)
28592864
{
2860-
PyObject *new;
28612865
Py_buffer view;
2862-
28632866
if (PyObject_GetBuffer(x, &view, PyBUF_FULL_RO) < 0)
28642867
return NULL;
28652868

2866-
new = PyBytes_FromStringAndSize(NULL, view.len);
2867-
if (!new)
2869+
PyBytesWriter *writer = PyBytesWriter_Create(view.len);
2870+
if (writer == NULL) {
28682871
goto fail;
2869-
if (PyBuffer_ToContiguous(((PyBytesObject *)new)->ob_sval,
2870-
&view, view.len, 'C') < 0)
2872+
}
2873+
2874+
if (PyBuffer_ToContiguous(PyBytesWriter_GetData(writer),
2875+
&view, view.len, 'C') < 0) {
28712876
goto fail;
2877+
}
2878+
28722879
PyBuffer_Release(&view);
2873-
return new;
2880+
return PyBytesWriter_Finish(writer);
28742881

28752882
fail:
2876-
Py_XDECREF(new);
2883+
PyBytesWriter_Discard(writer);
28772884
PyBuffer_Release(&view);
28782885
return NULL;
28792886
}
28802887

28812888
static PyObject*
28822889
_PyBytes_FromList(PyObject *x)
28832890
{
2884-
Py_ssize_t i, size = PyList_GET_SIZE(x);
2885-
Py_ssize_t value;
2886-
char *str;
2887-
PyObject *item;
2888-
_PyBytesWriter writer;
2889-
2890-
_PyBytesWriter_Init(&writer);
2891-
str = _PyBytesWriter_Alloc(&writer, size);
2892-
if (str == NULL)
2891+
Py_ssize_t size = PyList_GET_SIZE(x);
2892+
PyBytesWriter *writer = PyBytesWriter_Create(size);
2893+
if (writer == NULL) {
28932894
return NULL;
2894-
writer.overallocate = 1;
2895-
size = writer.allocated;
2895+
}
2896+
char *str = PyBytesWriter_GetData(writer);
2897+
size = _PyBytesWriter_GetAllocated(writer);
28962898

2897-
for (i = 0; i < PyList_GET_SIZE(x); i++) {
2898-
item = PyList_GET_ITEM(x, i);
2899+
for (Py_ssize_t i = 0; i < PyList_GET_SIZE(x); i++) {
2900+
PyObject *item = PyList_GET_ITEM(x, i);
28992901
Py_INCREF(item);
2900-
value = PyNumber_AsSsize_t(item, NULL);
2902+
Py_ssize_t value = PyNumber_AsSsize_t(item, NULL);
29012903
Py_DECREF(item);
29022904
if (value == -1 && PyErr_Occurred())
29032905
goto error;
@@ -2909,33 +2911,33 @@ _PyBytes_FromList(PyObject *x)
29092911
}
29102912

29112913
if (i >= size) {
2912-
str = _PyBytesWriter_Resize(&writer, str, size+1);
2913-
if (str == NULL)
2914-
return NULL;
2915-
size = writer.allocated;
2914+
str = _PyBytesWriter_ResizeAndUpdatePointer(writer, size + 1, str);
2915+
if (str == NULL) {
2916+
goto error;
2917+
}
2918+
size = _PyBytesWriter_GetAllocated(writer);
29162919
}
29172920
*str++ = (char) value;
29182921
}
2919-
return _PyBytesWriter_Finish(&writer, str);
2922+
return PyBytesWriter_FinishWithPointer(writer, str);
29202923

2921-
error:
2922-
_PyBytesWriter_Dealloc(&writer);
2924+
error:
2925+
PyBytesWriter_Discard(writer);
29232926
return NULL;
29242927
}
29252928

29262929
static PyObject*
29272930
_PyBytes_FromTuple(PyObject *x)
29282931
{
2929-
PyObject *bytes;
29302932
Py_ssize_t i, size = PyTuple_GET_SIZE(x);
29312933
Py_ssize_t value;
2932-
char *str;
29332934
PyObject *item;
29342935

2935-
bytes = PyBytes_FromStringAndSize(NULL, size);
2936-
if (bytes == NULL)
2936+
PyBytesWriter *writer = PyBytesWriter_Create(size);
2937+
if (writer == NULL) {
29372938
return NULL;
2938-
str = ((PyBytesObject *)bytes)->ob_sval;
2939+
}
2940+
char *str = PyBytesWriter_GetData(writer);
29392941

29402942
for (i = 0; i < size; i++) {
29412943
item = PyTuple_GET_ITEM(x, i);
@@ -2950,31 +2952,29 @@ _PyBytes_FromTuple(PyObject *x)
29502952
}
29512953
*str++ = (char) value;
29522954
}
2953-
return bytes;
2955+
return PyBytesWriter_Finish(writer);
29542956

29552957
error:
2956-
Py_DECREF(bytes);
2958+
PyBytesWriter_Discard(writer);
29572959
return NULL;
29582960
}
29592961

29602962
static PyObject *
29612963
_PyBytes_FromIterator(PyObject *it, PyObject *x)
29622964
{
2963-
char *str;
29642965
Py_ssize_t i, size;
2965-
_PyBytesWriter writer;
29662966

29672967
/* For iterator version, create a bytes object and resize as needed */
29682968
size = PyObject_LengthHint(x, 64);
29692969
if (size == -1 && PyErr_Occurred())
29702970
return NULL;
29712971

2972-
_PyBytesWriter_Init(&writer);
2973-
str = _PyBytesWriter_Alloc(&writer, size);
2974-
if (str == NULL)
2972+
PyBytesWriter *writer = PyBytesWriter_Create(size);
2973+
if (writer == NULL) {
29752974
return NULL;
2976-
writer.overallocate = 1;
2977-
size = writer.allocated;
2975+
}
2976+
char *str = PyBytesWriter_GetData(writer);
2977+
size = _PyBytesWriter_GetAllocated(writer);
29782978

29792979
/* Run the iterator to exhaustion */
29802980
for (i = 0; ; i++) {
@@ -3004,18 +3004,18 @@ _PyBytes_FromIterator(PyObject *it, PyObject *x)
30043004

30053005
/* Append the byte */
30063006
if (i >= size) {
3007-
str = _PyBytesWriter_Resize(&writer, str, size+1);
3008-
if (str == NULL)
3009-
return NULL;
3010-
size = writer.allocated;
3007+
str = _PyBytesWriter_ResizeAndUpdatePointer(writer, size + 1, str);
3008+
if (str == NULL) {
3009+
goto error;
3010+
}
3011+
size = _PyBytesWriter_GetAllocated(writer);
30113012
}
30123013
*str++ = (char) value;
30133014
}
3014-
3015-
return _PyBytesWriter_Finish(&writer, str);
3015+
return PyBytesWriter_FinishWithPointer(writer, str);
30163016

30173017
error:
3018-
_PyBytesWriter_Dealloc(&writer);
3018+
PyBytesWriter_Discard(writer);
30193019
return NULL;
30203020
}
30213021

@@ -3983,6 +3983,13 @@ PyBytesWriter_GetSize(PyBytesWriter *writer)
39833983
}
39843984

39853985

3986+
static Py_ssize_t
3987+
_PyBytesWriter_GetAllocated(PyBytesWriter *writer)
3988+
{
3989+
return byteswriter_allocated(writer);
3990+
}
3991+
3992+
39863993
int
39873994
PyBytesWriter_Resize(PyBytesWriter *writer, Py_ssize_t size)
39883995
{
@@ -3998,6 +4005,18 @@ PyBytesWriter_Resize(PyBytesWriter *writer, Py_ssize_t size)
39984005
}
39994006

40004007

4008+
static void*
4009+
_PyBytesWriter_ResizeAndUpdatePointer(PyBytesWriter *writer, Py_ssize_t size,
4010+
void *data)
4011+
{
4012+
Py_ssize_t pos = (char*)data - byteswriter_data(writer);
4013+
if (PyBytesWriter_Resize(writer, size) < 0) {
4014+
return NULL;
4015+
}
4016+
return byteswriter_data(writer) + pos;
4017+
}
4018+
4019+
40014020
int
40024021
PyBytesWriter_Grow(PyBytesWriter *writer, Py_ssize_t size)
40034022
{

0 commit comments

Comments
 (0)