From: Victor Stinner Date: Mon, 15 Sep 2025 14:21:43 +0000 (+0100) Subject: gh-129813, PEP 782: Use PyBytesWriter in fcntl (#138921) X-Git-Tag: v3.15.0a1~366 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f07ae274b8e98c570d40b1aabd4cc42cb44a13ca;p=thirdparty%2FPython%2Fcpython.git 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. --- diff --git a/Modules/clinic/fcntlmodule.c.h b/Modules/clinic/fcntlmodule.c.h index 005e9b9e12af..2b61d9f87083 100644 --- a/Modules/clinic/fcntlmodule.c.h +++ b/Modules/clinic/fcntlmodule.c.h @@ -2,6 +2,8 @@ preserve [clinic start generated code]*/ +#include "pycore_modsupport.h" // _PyArg_CheckPositional() + PyDoc_STRVAR(fcntl_fcntl__doc__, "fcntl($module, fd, cmd, arg=0, /)\n" "--\n" @@ -19,7 +21,7 @@ PyDoc_STRVAR(fcntl_fcntl__doc__, "corresponding to the return value of the fcntl call in the C code."); #define FCNTL_FCNTL_METHODDEF \ - {"fcntl", (PyCFunction)(void(*)(void))fcntl_fcntl, METH_FASTCALL, fcntl_fcntl__doc__}, + {"fcntl", _PyCFunction_CAST(fcntl_fcntl), METH_FASTCALL, fcntl_fcntl__doc__}, static PyObject * fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg); @@ -32,12 +34,7 @@ fcntl_fcntl(PyObject *module, PyObject *const *args, Py_ssize_t nargs) int code; PyObject *arg = NULL; - if (nargs < 2) { - PyErr_Format(PyExc_TypeError, "fcntl expected at least 2 arguments, got %zd", nargs); - goto exit; - } - if (nargs > 3) { - PyErr_Format(PyExc_TypeError, "fcntl expected at most 3 arguments, got %zd", nargs); + if (!_PyArg_CheckPositional("fcntl", nargs, 2, 3)) { goto exit; } fd = PyObject_AsFileDescriptor(args[0]); @@ -93,7 +90,7 @@ PyDoc_STRVAR(fcntl_ioctl__doc__, "code."); #define FCNTL_IOCTL_METHODDEF \ - {"ioctl", (PyCFunction)(void(*)(void))fcntl_ioctl, METH_FASTCALL, fcntl_ioctl__doc__}, + {"ioctl", _PyCFunction_CAST(fcntl_ioctl), METH_FASTCALL, fcntl_ioctl__doc__}, static PyObject * fcntl_ioctl_impl(PyObject *module, int fd, unsigned long code, PyObject *arg, @@ -108,12 +105,7 @@ fcntl_ioctl(PyObject *module, PyObject *const *args, Py_ssize_t nargs) PyObject *arg = NULL; int mutate_arg = 1; - if (nargs < 2) { - PyErr_Format(PyExc_TypeError, "ioctl expected at least 2 arguments, got %zd", nargs); - goto exit; - } - if (nargs > 4) { - PyErr_Format(PyExc_TypeError, "ioctl expected at most 4 arguments, got %zd", nargs); + if (!_PyArg_CheckPositional("ioctl", nargs, 2, 4)) { goto exit; } fd = PyObject_AsFileDescriptor(args[0]); @@ -121,7 +113,7 @@ fcntl_ioctl(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyIndex_Check(args[1])) { - PyErr_Format(PyExc_TypeError, "ioctl() argument 2 must be int, not %T", args[1]); + _PyArg_BadArgument("ioctl", "argument 2", "int", args[1]); goto exit; } { @@ -168,7 +160,7 @@ PyDoc_STRVAR(fcntl_flock__doc__, "function is emulated using fcntl())."); #define FCNTL_FLOCK_METHODDEF \ - {"flock", (PyCFunction)(void(*)(void))fcntl_flock, METH_FASTCALL, fcntl_flock__doc__}, + {"flock", _PyCFunction_CAST(fcntl_flock), METH_FASTCALL, fcntl_flock__doc__}, static PyObject * fcntl_flock_impl(PyObject *module, int fd, int code); @@ -180,8 +172,7 @@ fcntl_flock(PyObject *module, PyObject *const *args, Py_ssize_t nargs) int fd; int code; - if (nargs != 2) { - PyErr_Format(PyExc_TypeError, "flock expected 2 arguments, got %zd", nargs); + if (!_PyArg_CheckPositional("flock", nargs, 2, 2)) { goto exit; } fd = PyObject_AsFileDescriptor(args[0]); @@ -226,7 +217,7 @@ PyDoc_STRVAR(fcntl_lockf__doc__, " 2 - relative to the end of the file (SEEK_END)"); #define FCNTL_LOCKF_METHODDEF \ - {"lockf", (PyCFunction)(void(*)(void))fcntl_lockf, METH_FASTCALL, fcntl_lockf__doc__}, + {"lockf", _PyCFunction_CAST(fcntl_lockf), METH_FASTCALL, fcntl_lockf__doc__}, static PyObject * fcntl_lockf_impl(PyObject *module, int fd, int code, PyObject *lenobj, @@ -242,12 +233,7 @@ fcntl_lockf(PyObject *module, PyObject *const *args, Py_ssize_t nargs) PyObject *startobj = NULL; int whence = 0; - if (nargs < 2) { - PyErr_Format(PyExc_TypeError, "lockf expected at least 2 arguments, got %zd", nargs); - goto exit; - } - if (nargs > 5) { - PyErr_Format(PyExc_TypeError, "lockf expected at most 5 arguments, got %zd", nargs); + if (!_PyArg_CheckPositional("lockf", nargs, 2, 5)) { goto exit; } fd = PyObject_AsFileDescriptor(args[0]); @@ -279,4 +265,4 @@ skip_optional: exit: return return_value; } -/*[clinic end generated code: output=bf84289b741e7cf6 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=9773e44da302dc7c input=a9049054013a1b77]*/ diff --git a/Modules/fcntlmodule.c b/Modules/fcntlmodule.c index e49bf81b61f3..df2c99941279 100644 --- a/Modules/fcntlmodule.c +++ b/Modules/fcntlmodule.c @@ -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 }