Hi,
I propose adding a PyBytesWriter
public C API to create a bytes
object. It replaces the PyBytes_FromStringAndSize(NULL, size)
, which creates an inconsistent bytes
objects (bytes are not initialized), and _PyBytes_Resize()
, which treats an immutable bytes
object as a mutable object. Proposed API only produces a bytes
object once writing is complete: when PyBytesWriter_Finish()
is called.
The PyBytesWriter_Extend()
function overallocates the buffer to reduce the cost of multiple reallocations.
The API gives a void*
pointer (which can be cast to char*
) so the main code works directly on regular fast pointer operations, rather than going through an abstraction.
API:
typedef struct PyBytesWriter PyBytesWriter;
PyAPI_FUNC(void*) PyBytesWriter_Create(
PyBytesWriter **writer,
Py_ssize_t alloc);
PyAPI_FUNC(void) PyBytesWriter_Discard(
PyBytesWriter *writer);
PyAPI_FUNC(PyObject*) PyBytesWriter_Finish(
PyBytesWriter *writer,
void *buf);
PyAPI_FUNC(Py_ssize_t) PyBytesWriter_GetRemaining(
PyBytesWriter *writer,
void *buf);
PyAPI_FUNC(void*) PyBytesWriter_Extend(
PyBytesWriter *writer,
void *buf,
Py_ssize_t extend);
PyAPI_FUNC(void*) PyBytesWriter_WriteBytes(
PyBytesWriter *writer,
void *buf,
const void *bytes,
Py_ssize_t size);
PyAPI_FUNC(void*) PyBytesWriter_Format(
PyBytesWriter *writer,
void *buf,
const char *format,
...);
Simple example creating the string b"abc"
:
PyObject* create_abc(void)
{
PyBytesWriter *writer;
char *str = PyBytesWriter_Create(&writer, 3);
if (writer == NULL) return NULL;
memcpy(str, "abc", 3);
str += 3;
return PyBytesWriter_Finish(writer, str);
}
See also:
- Pull request: API, documentation, full implementation
- Issue: More examples, discussion
What do you think of the proposed public C API?
Victor