gh-129813, PEP 782: Use PyBytesWriter in fcntl (#138921)

Replace PyBytes_FromStringAndSize(NULL, size) with the new public
PyBytesWriter API.

Don't build the fcntl with the limited C API anymore, since
the PyBytesWriter API is not part of the limited C API.
This commit is contained in:
Victor Stinner 2025-09-15 15:21:43 +01:00 committed by GitHub
parent 43013f72f0
commit f07ae274b8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 27 additions and 42 deletions

View file

@ -1,9 +1,8 @@
/* fcntl module */
// Need limited C API version 3.14 for PyLong_AsNativeBytes() in AC code
#include "pyconfig.h" // Py_GIL_DISABLED
#ifndef Py_GIL_DISABLED
# define Py_LIMITED_API 0x030e0000
// Argument Clinic uses the internal C API
#ifndef Py_BUILD_CORE_BUILTIN
# define Py_BUILD_CORE_MODULE 1
#endif
#include "Python.h"
@ -113,12 +112,12 @@ fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg)
return PyBytes_FromStringAndSize(buf, len);
}
else {
PyObject *result = PyBytes_FromStringAndSize(NULL, len);
if (result == NULL) {
PyBytesWriter *writer = PyBytesWriter_Create(len);
if (writer == NULL) {
PyBuffer_Release(&view);
return NULL;
}
char *ptr = PyBytes_AsString(result);
char *ptr = PyBytesWriter_GetData(writer);
memcpy(ptr, view.buf, len);
PyBuffer_Release(&view);
@ -131,15 +130,15 @@ fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg)
if (!async_err) {
PyErr_SetFromErrno(PyExc_OSError);
}
Py_DECREF(result);
PyBytesWriter_Discard(writer);
return NULL;
}
if (ptr[len] != '\0') {
PyErr_SetString(PyExc_SystemError, "buffer overflow");
Py_DECREF(result);
PyBytesWriter_Discard(writer);
return NULL;
}
return result;
return PyBytesWriter_Finish(writer);
}
#undef FCNTL_BUFSZ
}
@ -297,12 +296,12 @@ fcntl_ioctl_impl(PyObject *module, int fd, unsigned long code, PyObject *arg,
return PyBytes_FromStringAndSize(buf, len);
}
else {
PyObject *result = PyBytes_FromStringAndSize(NULL, len);
if (result == NULL) {
PyBytesWriter *writer = PyBytesWriter_Create(len);
if (writer == NULL) {
PyBuffer_Release(&view);
return NULL;
}
char *ptr = PyBytes_AsString(result);
char *ptr = PyBytesWriter_GetData(writer);
memcpy(ptr, view.buf, len);
PyBuffer_Release(&view);
@ -315,15 +314,15 @@ fcntl_ioctl_impl(PyObject *module, int fd, unsigned long code, PyObject *arg,
if (!async_err) {
PyErr_SetFromErrno(PyExc_OSError);
}
Py_DECREF(result);
PyBytesWriter_Discard(writer);
return NULL;
}
if (ptr[len] != '\0') {
PyErr_SetString(PyExc_SystemError, "buffer overflow");
Py_DECREF(result);
PyBytesWriter_Discard(writer);
return NULL;
}
return result;
return PyBytesWriter_Finish(writer);
}
#undef IOCTL_BUFSZ
}