Description
This API is basically an efficient memory manager for functions creating Python bytes objects.
It avoids the creation of incomplete/inconsistent Python bytes objects: allocate an object with uninitialized bytes, fill the object, resize it. See issues:
- Avoid creating incomplete/invalid objects api-evolution#36
- Disallow mutating immutable objects api-evolution#20
- Disallow creation of incomplete/inconsistent objects problems#56
API:
// Create a bytes writer instance.
PyBytesWriter* PyBytesWriter_Create(Py_ssize_t size, char **str);
// Return the final Python bytes object and destroy the writer instance.
PyObject* PyBytesWriter_Finish(PyBytesWriter *writer, char *str);
// Discard the internal bytes buffer and destroy the writer instance.
void PyBytesWriter_Discard(PyBytesWriter *writer);
// Allocate *size* bytes to prepare writing *size* bytes into *writer*.
int PyBytesWriter_Prepare(PyBytesWriter *writer, char **str, Py_ssize_t size);
// Write a the bytes string *bytes* of *size* bytes into *writer*.
int PyBytesWriter_WriteBytes(PyBytesWriter *writer, char **str, const void *bytes, Py_ssize_t size);
The str parameter is what's being used to write bytes in the writer.
Example creating the string "abc":
static PyObject* create_abc(void)
{
char *str;
PyBytesWriter *writer = PyBytesWriter_Create(3, &str);
if (writer == NULL) return NULL;
// Write "abc"
memcpy(str, "abc", 3);
str += 3;
return PyBytesWriter_Finish(writer, str);
}
The "hot code" which writes bytes can only use str.
The PyBytesWriter_WriteBytes()
is just a small convenient helper function (for PyBytesWriter_Prepare()
+ memcpy()
calls).
You can find more documentation and examples in the Pull Request.
This proposed public API is based on existing _PyBytesWriter
API which is quite old. I wrote an article about it in 2016: https://vstinner.github.io/pybyteswriter.html