gh-129813, PEP 782: Use PyBytesWriter in posix extension (#138829)

Replace PyBytes_FromStringAndSize(NULL, size) and _PyBytes_Resize()
with the new public PyBytesWriter API.
This commit is contained in:
Victor Stinner 2025-09-13 18:57:46 +02:00 committed by GitHub
parent 703da5e81d
commit af386fd361
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -11507,9 +11507,6 @@ static PyObject *
os_read_impl(PyObject *module, int fd, Py_ssize_t length)
/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
{
Py_ssize_t n;
PyObject *buffer;
if (length < 0) {
errno = EINVAL;
return posix_error();
@ -11517,20 +11514,18 @@ os_read_impl(PyObject *module, int fd, Py_ssize_t length)
length = Py_MIN(length, _PY_READ_MAX);
buffer = PyBytes_FromStringAndSize((char *)NULL, length);
if (buffer == NULL)
return NULL;
n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
if (n == -1) {
Py_DECREF(buffer);
PyBytesWriter *writer = PyBytesWriter_Create(length);
if (writer == NULL) {
return NULL;
}
if (n != length)
_PyBytes_Resize(&buffer, n);
Py_ssize_t n = _Py_read(fd, PyBytesWriter_GetData(writer), length);
if (n == -1) {
PyBytesWriter_Discard(writer);
return NULL;
}
return buffer;
return PyBytesWriter_FinishWithSize(writer, n);
}
/*[clinic input]
@ -11708,20 +11703,20 @@ os_pread_impl(PyObject *module, int fd, Py_ssize_t length, Py_off_t offset)
{
Py_ssize_t n;
int async_err = 0;
PyObject *buffer;
if (length < 0) {
errno = EINVAL;
return posix_error();
}
buffer = PyBytes_FromStringAndSize((char *)NULL, length);
if (buffer == NULL)
PyBytesWriter *writer = PyBytesWriter_Create(length);
if (writer == NULL) {
return NULL;
}
do {
Py_BEGIN_ALLOW_THREADS
_Py_BEGIN_SUPPRESS_IPH
n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
n = pread(fd, PyBytesWriter_GetData(writer), length, offset);
_Py_END_SUPPRESS_IPH
Py_END_ALLOW_THREADS
} while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
@ -11730,12 +11725,10 @@ os_pread_impl(PyObject *module, int fd, Py_ssize_t length, Py_off_t offset)
if (!async_err) {
posix_error();
}
Py_DECREF(buffer);
PyBytesWriter_Discard(writer);
return NULL;
}
if (n != length)
_PyBytes_Resize(&buffer, n);
return buffer;
return PyBytesWriter_FinishWithSize(writer, n);
}
#endif /* HAVE_PREAD */
@ -14945,9 +14938,6 @@ os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
int follow_symlinks)
/*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/
{
Py_ssize_t i;
PyObject *buffer = NULL;
if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
return NULL;
@ -14955,8 +14945,7 @@ os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
return NULL;
}
for (i = 0; ; i++) {
void *ptr;
for (Py_ssize_t i = 0; ; i++) {
ssize_t result;
static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Py_ssize_t buffer_size = buffer_sizes[i];
@ -14964,10 +14953,11 @@ os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
path_error(path);
return NULL;
}
buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
if (!buffer)
PyBytesWriter *writer = PyBytesWriter_Create(buffer_size);
if (writer == NULL) {
return NULL;
ptr = PyBytes_AS_STRING(buffer);
}
void *ptr = PyBytesWriter_GetData(writer);
Py_BEGIN_ALLOW_THREADS;
if (path->fd >= 0)
@ -14979,23 +14969,16 @@ os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Py_END_ALLOW_THREADS;
if (result < 0) {
PyBytesWriter_Discard(writer);
if (errno == ERANGE) {
Py_DECREF(buffer);
continue;
}
path_error(path);
Py_DECREF(buffer);
return NULL;
}
if (result != buffer_size) {
/* Can only shrink. */
_PyBytes_Resize(&buffer, result);
}
break;
return PyBytesWriter_FinishWithSize(writer, result);
}
return buffer;
}
@ -15222,19 +15205,22 @@ static PyObject *
os_urandom_impl(PyObject *module, Py_ssize_t size)
/*[clinic end generated code: output=42c5cca9d18068e9 input=58a0def87dbc2c22]*/
{
PyObject *bytes;
int result;
if (size < 0) {
return PyErr_Format(PyExc_ValueError,
"negative argument not allowed");
}
bytes = PyBytes_FromStringAndSize(NULL, size);
if (bytes == NULL)
return NULL;
result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
if (result == -1) {
Py_DECREF(bytes);
PyBytesWriter *writer = PyBytesWriter_Create(size);
if (writer == NULL) {
return NULL;
}
return bytes;
int result = _PyOS_URandom(PyBytesWriter_GetData(writer), size);
if (result == -1) {
PyBytesWriter_Discard(writer);
return NULL;
}
return PyBytesWriter_Finish(writer);
}
#ifdef HAVE_MEMFD_CREATE
@ -16704,25 +16690,20 @@ static PyObject *
os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
{
PyObject *bytes;
Py_ssize_t n;
if (size < 0) {
errno = EINVAL;
return posix_error();
}
bytes = PyBytes_FromStringAndSize(NULL, size);
if (bytes == NULL) {
PyErr_NoMemory();
PyBytesWriter *writer = PyBytesWriter_Create(size);
if (writer == NULL) {
return NULL;
}
void *data = PyBytesWriter_GetData(writer);
Py_ssize_t n;
while (1) {
n = syscall(SYS_getrandom,
PyBytes_AS_STRING(bytes),
PyBytes_GET_SIZE(bytes),
flags);
n = syscall(SYS_getrandom, data, size, flags);
if (n < 0 && errno == EINTR) {
if (PyErr_CheckSignals() < 0) {
goto error;
@ -16739,14 +16720,10 @@ os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
goto error;
}
if (n != size) {
_PyBytes_Resize(&bytes, n);
}
return bytes;
return PyBytesWriter_FinishWithSize(writer, n);
error:
Py_DECREF(bytes);
PyBytesWriter_Discard(writer);
return NULL;
}
#endif /* HAVE_GETRANDOM_SYSCALL */