https://github.com/python/cpython/commit/f07ae274b8e98c570d40b1aabd4cc42cb44a13ca
commit: f07ae274b8e98c570d40b1aabd4cc42cb44a13ca
branch: main
author: Victor Stinner <[email protected]>
committer: vstinner <[email protected]>
date: 2025-09-15T16:21:43+02:00
summary:
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.
files:
M Modules/clinic/fcntlmodule.c.h
M Modules/fcntlmodule.c
diff --git a/Modules/clinic/fcntlmodule.c.h b/Modules/clinic/fcntlmodule.c.h
index 005e9b9e12afd9..2b61d9f87083f0 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 @@ fcntl_lockf(PyObject *module, PyObject *const *args,
Py_ssize_t nargs)
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 e49bf81b61f3be..df2c9994127997 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
}
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]