From 98dd91bf8e2a7122faedbeedd1f842dd1a30b019 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 10 May 2023 13:08:22 +0200 Subject: [PATCH 1/6] gh-101819: Adapt _io._BufferedIOBase_Type methods to Argument Clinic Make sure the defining class is passed to all methods, so we can easily fetch module state from them in the future. --- Modules/_io/bufferedio.c | 91 +++++++++++++++++------------- Modules/_io/clinic/bufferedio.c.h | 94 +++++++++++++++++++++++++++++-- 2 files changed, 141 insertions(+), 44 deletions(-) diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index 172fafe6db8a3d..d72937f6a01a16 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -115,6 +115,9 @@ bufferediobase_unsupported(_PyIO_State *state, const char *message) /*[clinic input] _io._BufferedIOBase.detach + cls: defining_class + / + Disconnect this buffer from its underlying raw stream and return it. After the raw stream has been detached, the buffer is in an unusable @@ -122,63 +125,73 @@ state. [clinic start generated code]*/ static PyObject * -_io__BufferedIOBase_detach_impl(PyObject *self) -/*[clinic end generated code: output=754977c8d10ed88c input=822427fb58fe4169]*/ +_io__BufferedIOBase_detach_impl(PyObject *self, PyTypeObject *cls) +/*[clinic end generated code: output=b87b135d67cd4448 input=0b61a7b4357c1ea7]*/ { _PyIO_State *state = IO_STATE(); return bufferediobase_unsupported(state, "detach"); } -PyDoc_STRVAR(bufferediobase_read_doc, - "Read and return up to n bytes.\n" - "\n" - "If the argument is omitted, None, or negative, reads and\n" - "returns all data until EOF.\n" - "\n" - "If the argument is positive, and the underlying raw stream is\n" - "not 'interactive', multiple raw reads may be issued to satisfy\n" - "the byte count (unless EOF is reached first). But for\n" - "interactive raw streams (as well as sockets and pipes), at most\n" - "one raw read will be issued, and a short result does not imply\n" - "that EOF is imminent.\n" - "\n" - "Returns an empty bytes object on EOF.\n" - "\n" - "Returns None if the underlying raw stream was open in non-blocking\n" - "mode and no data is available at the moment.\n"); +/*[clinic input] +_io._BufferedIOBase.read + + cls: defining_class + / + +Read and return up to n bytes. + +If the argument is omitted, None, or negative, reads and returns all data until EOF. + +If the argument is positive, and the underlying raw stream is not 'interactive', multiple raw reads may be issued to satisfy the byte count (unless EOF is reached first). But for interactive raw streams (as well as sockets and pipes), at most one raw read will be issued, and a short result does not imply that EOF is imminent. + +Return an empty bytes object on EOF. + +Return None if the underlying raw stream was open in non-blocking mode and no data is available at the moment. +[clinic start generated code]*/ static PyObject * -bufferediobase_read(PyObject *self, PyObject *args) +_io__BufferedIOBase_read_impl(PyObject *self, PyTypeObject *cls) +/*[clinic end generated code: output=905b1b6ea25c0aa5 input=a5ee8e4e31eddfe3]*/ { _PyIO_State *state = IO_STATE(); return bufferediobase_unsupported(state, "read"); } -PyDoc_STRVAR(bufferediobase_read1_doc, - "Read and return up to n bytes, with at most one read() call\n" - "to the underlying raw stream. A short result does not imply\n" - "that EOF is imminent.\n" - "\n" - "Returns an empty bytes object on EOF.\n"); +/*[clinic input] +_io._BufferedIOBase.read1 + + cls: defining_class + / + +Read and return up to n bytes, with at most one read() call to the underlying raw stream. A short result does not imply that EOF is imminent. + +Return an empty bytes object on EOF. +[clinic start generated code]*/ static PyObject * -bufferediobase_read1(PyObject *self, PyObject *args) +_io__BufferedIOBase_read1_impl(PyObject *self, PyTypeObject *cls) +/*[clinic end generated code: output=999785c4a78817bf input=8a1399f50844a8f9]*/ { _PyIO_State *state = IO_STATE(); return bufferediobase_unsupported(state, "read1"); } -PyDoc_STRVAR(bufferediobase_write_doc, - "Write the given buffer to the IO stream.\n" - "\n" - "Returns the number of bytes written, which is always the length of b\n" - "in bytes.\n" - "\n" - "Raises BlockingIOError if the buffer is full and the\n" - "underlying raw stream cannot accept more data at the moment.\n"); +/*[clinic input] +_io._BufferedIOBase.write + + cls: defining_class + / + +Write the given buffer to the IO stream. + +Return the number of bytes written, which is always the length of b in bytes. + +Raise BlockingIOError if the buffer is full and the underlying raw stream cannot accept more data at the moment. +[clinic start generated code]*/ static PyObject * -bufferediobase_write(PyObject *self, PyObject *args) +_io__BufferedIOBase_write_impl(PyObject *self, PyTypeObject *cls) +/*[clinic end generated code: output=be944cf83e6f7356 input=dafbf71f2e70e1ff]*/ { _PyIO_State *state = IO_STATE(); return bufferediobase_unsupported(state, "write"); @@ -2336,11 +2349,11 @@ _io_BufferedRandom___init___impl(buffered *self, PyObject *raw, static PyMethodDef bufferediobase_methods[] = { _IO__BUFFEREDIOBASE_DETACH_METHODDEF - {"read", bufferediobase_read, METH_VARARGS, bufferediobase_read_doc}, - {"read1", bufferediobase_read1, METH_VARARGS, bufferediobase_read1_doc}, + _IO__BUFFEREDIOBASE_READ_METHODDEF + _IO__BUFFEREDIOBASE_READ1_METHODDEF _IO__BUFFEREDIOBASE_READINTO_METHODDEF _IO__BUFFEREDIOBASE_READINTO1_METHODDEF - {"write", bufferediobase_write, METH_VARARGS, bufferediobase_write_doc}, + _IO__BUFFEREDIOBASE_WRITE_METHODDEF {NULL, NULL} }; diff --git a/Modules/_io/clinic/bufferedio.c.h b/Modules/_io/clinic/bufferedio.c.h index d44321bb8b960e..bb6293b6ff2c18 100644 --- a/Modules/_io/clinic/bufferedio.c.h +++ b/Modules/_io/clinic/bufferedio.c.h @@ -92,15 +92,99 @@ PyDoc_STRVAR(_io__BufferedIOBase_detach__doc__, "state."); #define _IO__BUFFEREDIOBASE_DETACH_METHODDEF \ - {"detach", (PyCFunction)_io__BufferedIOBase_detach, METH_NOARGS, _io__BufferedIOBase_detach__doc__}, + {"detach", _PyCFunction_CAST(_io__BufferedIOBase_detach), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__BufferedIOBase_detach__doc__}, static PyObject * -_io__BufferedIOBase_detach_impl(PyObject *self); +_io__BufferedIOBase_detach_impl(PyObject *self, PyTypeObject *cls); static PyObject * -_io__BufferedIOBase_detach(PyObject *self, PyObject *Py_UNUSED(ignored)) +_io__BufferedIOBase_detach(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _io__BufferedIOBase_detach_impl(self); + if (nargs) { + PyErr_SetString(PyExc_TypeError, "detach() takes no arguments"); + return NULL; + } + return _io__BufferedIOBase_detach_impl(self, cls); +} + +PyDoc_STRVAR(_io__BufferedIOBase_read__doc__, +"read($self, /)\n" +"--\n" +"\n" +"Read and return up to n bytes.\n" +"\n" +"If the argument is omitted, None, or negative, reads and returns all data until EOF.\n" +"\n" +"If the argument is positive, and the underlying raw stream is not \'interactive\', multiple raw reads may be issued to satisfy the byte count (unless EOF is reached first). But for interactive raw streams (as well as sockets and pipes), at most one raw read will be issued, and a short result does not imply that EOF is imminent.\n" +"\n" +"Return an empty bytes object on EOF.\n" +"\n" +"Return None if the underlying raw stream was open in non-blocking mode and no data is available at the moment."); + +#define _IO__BUFFEREDIOBASE_READ_METHODDEF \ + {"read", _PyCFunction_CAST(_io__BufferedIOBase_read), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__BufferedIOBase_read__doc__}, + +static PyObject * +_io__BufferedIOBase_read_impl(PyObject *self, PyTypeObject *cls); + +static PyObject * +_io__BufferedIOBase_read(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + if (nargs) { + PyErr_SetString(PyExc_TypeError, "read() takes no arguments"); + return NULL; + } + return _io__BufferedIOBase_read_impl(self, cls); +} + +PyDoc_STRVAR(_io__BufferedIOBase_read1__doc__, +"read1($self, /)\n" +"--\n" +"\n" +"Read and return up to n bytes, with at most one read() call to the underlying raw stream. A short result does not imply that EOF is imminent.\n" +"\n" +"Return an empty bytes object on EOF."); + +#define _IO__BUFFEREDIOBASE_READ1_METHODDEF \ + {"read1", _PyCFunction_CAST(_io__BufferedIOBase_read1), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__BufferedIOBase_read1__doc__}, + +static PyObject * +_io__BufferedIOBase_read1_impl(PyObject *self, PyTypeObject *cls); + +static PyObject * +_io__BufferedIOBase_read1(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + if (nargs) { + PyErr_SetString(PyExc_TypeError, "read1() takes no arguments"); + return NULL; + } + return _io__BufferedIOBase_read1_impl(self, cls); +} + +PyDoc_STRVAR(_io__BufferedIOBase_write__doc__, +"write($self, /)\n" +"--\n" +"\n" +"Write the given buffer to the IO stream.\n" +"\n" +"Return the number of bytes written, which is always the length of b in bytes.\n" +"\n" +"Raise BlockingIOError if the buffer is full and the underlying raw stream cannot accept more data at the moment."); + +#define _IO__BUFFEREDIOBASE_WRITE_METHODDEF \ + {"write", _PyCFunction_CAST(_io__BufferedIOBase_write), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__BufferedIOBase_write__doc__}, + +static PyObject * +_io__BufferedIOBase_write_impl(PyObject *self, PyTypeObject *cls); + +static PyObject * +_io__BufferedIOBase_write(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + if (nargs) { + PyErr_SetString(PyExc_TypeError, "write() takes no arguments"); + return NULL; + } + return _io__BufferedIOBase_write_impl(self, cls); } PyDoc_STRVAR(_io__Buffered_peek__doc__, @@ -714,4 +798,4 @@ _io_BufferedRandom___init__(PyObject *self, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=8412b10c04259bb8 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=86cfa7f53e470cd9 input=a9049054013a1b77]*/ From fc1401963d8d0afb99501bf4396bcc1dc89b1f6f Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 10 May 2023 13:15:01 +0200 Subject: [PATCH 2/6] Wrap docstrings --- Modules/_io/bufferedio.c | 28 +++++++++++++++++++--------- Modules/_io/clinic/bufferedio.c.h | 26 ++++++++++++++++++-------- 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index d72937f6a01a16..73e1b833991172 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -140,18 +140,25 @@ _io._BufferedIOBase.read Read and return up to n bytes. -If the argument is omitted, None, or negative, reads and returns all data until EOF. +If the argument is omitted, None, or negative, reads and +returns all data until EOF -If the argument is positive, and the underlying raw stream is not 'interactive', multiple raw reads may be issued to satisfy the byte count (unless EOF is reached first). But for interactive raw streams (as well as sockets and pipes), at most one raw read will be issued, and a short result does not imply that EOF is imminent. +If the argument is positive, and the underlying raw stream is +not 'interactive', multiple raw reads may be issued to satisfy +the byte count (unless EOF is reached first). +But for interactive raw streams (as well as sockets and pipes), +at most one raw read will be issued, and a short result does not +imply that EOF is imminent. Return an empty bytes object on EOF. -Return None if the underlying raw stream was open in non-blocking mode and no data is available at the moment. +Return None if the underlying raw stream was open in non-blocking +mode and no data is available at the moment. [clinic start generated code]*/ static PyObject * _io__BufferedIOBase_read_impl(PyObject *self, PyTypeObject *cls) -/*[clinic end generated code: output=905b1b6ea25c0aa5 input=a5ee8e4e31eddfe3]*/ +/*[clinic end generated code: output=905b1b6ea25c0aa5 input=52e347baff1c191c]*/ { _PyIO_State *state = IO_STATE(); return bufferediobase_unsupported(state, "read"); @@ -163,14 +170,15 @@ _io._BufferedIOBase.read1 cls: defining_class / -Read and return up to n bytes, with at most one read() call to the underlying raw stream. A short result does not imply that EOF is imminent. +Read and return up to n bytes, with at most one read() call to the underlying raw stream. Return an empty bytes object on EOF. +A short result does not imply that EOF is imminent. [clinic start generated code]*/ static PyObject * _io__BufferedIOBase_read1_impl(PyObject *self, PyTypeObject *cls) -/*[clinic end generated code: output=999785c4a78817bf input=8a1399f50844a8f9]*/ +/*[clinic end generated code: output=999785c4a78817bf input=c38f07e1be5ee79d]*/ { _PyIO_State *state = IO_STATE(); return bufferediobase_unsupported(state, "read1"); @@ -184,14 +192,16 @@ _io._BufferedIOBase.write Write the given buffer to the IO stream. -Return the number of bytes written, which is always the length of b in bytes. +Return the number of bytes written, which is always +the length of b in bytes. -Raise BlockingIOError if the buffer is full and the underlying raw stream cannot accept more data at the moment. +Raise BlockingIOError if the buffer is full and the +underlying raw stream cannot accept more data at the moment. [clinic start generated code]*/ static PyObject * _io__BufferedIOBase_write_impl(PyObject *self, PyTypeObject *cls) -/*[clinic end generated code: output=be944cf83e6f7356 input=dafbf71f2e70e1ff]*/ +/*[clinic end generated code: output=be944cf83e6f7356 input=02b37c30f28e4882]*/ { _PyIO_State *state = IO_STATE(); return bufferediobase_unsupported(state, "write"); diff --git a/Modules/_io/clinic/bufferedio.c.h b/Modules/_io/clinic/bufferedio.c.h index bb6293b6ff2c18..4797c39173ca16 100644 --- a/Modules/_io/clinic/bufferedio.c.h +++ b/Modules/_io/clinic/bufferedio.c.h @@ -113,13 +113,20 @@ PyDoc_STRVAR(_io__BufferedIOBase_read__doc__, "\n" "Read and return up to n bytes.\n" "\n" -"If the argument is omitted, None, or negative, reads and returns all data until EOF.\n" +"If the argument is omitted, None, or negative, reads and\n" +"returns all data until EOF\n" "\n" -"If the argument is positive, and the underlying raw stream is not \'interactive\', multiple raw reads may be issued to satisfy the byte count (unless EOF is reached first). But for interactive raw streams (as well as sockets and pipes), at most one raw read will be issued, and a short result does not imply that EOF is imminent.\n" +"If the argument is positive, and the underlying raw stream is\n" +"not \'interactive\', multiple raw reads may be issued to satisfy\n" +"the byte count (unless EOF is reached first).\n" +"But for interactive raw streams (as well as sockets and pipes),\n" +"at most one raw read will be issued, and a short result does not\n" +"imply that EOF is imminent.\n" "\n" "Return an empty bytes object on EOF.\n" "\n" -"Return None if the underlying raw stream was open in non-blocking mode and no data is available at the moment."); +"Return None if the underlying raw stream was open in non-blocking\n" +"mode and no data is available at the moment."); #define _IO__BUFFEREDIOBASE_READ_METHODDEF \ {"read", _PyCFunction_CAST(_io__BufferedIOBase_read), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__BufferedIOBase_read__doc__}, @@ -141,9 +148,10 @@ PyDoc_STRVAR(_io__BufferedIOBase_read1__doc__, "read1($self, /)\n" "--\n" "\n" -"Read and return up to n bytes, with at most one read() call to the underlying raw stream. A short result does not imply that EOF is imminent.\n" +"Read and return up to n bytes, with at most one read() call to the underlying raw stream.\n" "\n" -"Return an empty bytes object on EOF."); +"Return an empty bytes object on EOF.\n" +"A short result does not imply that EOF is imminent."); #define _IO__BUFFEREDIOBASE_READ1_METHODDEF \ {"read1", _PyCFunction_CAST(_io__BufferedIOBase_read1), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__BufferedIOBase_read1__doc__}, @@ -167,9 +175,11 @@ PyDoc_STRVAR(_io__BufferedIOBase_write__doc__, "\n" "Write the given buffer to the IO stream.\n" "\n" -"Return the number of bytes written, which is always the length of b in bytes.\n" +"Return the number of bytes written, which is always\n" +"the length of b in bytes.\n" "\n" -"Raise BlockingIOError if the buffer is full and the underlying raw stream cannot accept more data at the moment."); +"Raise BlockingIOError if the buffer is full and the\n" +"underlying raw stream cannot accept more data at the moment."); #define _IO__BUFFEREDIOBASE_WRITE_METHODDEF \ {"write", _PyCFunction_CAST(_io__BufferedIOBase_write), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__BufferedIOBase_write__doc__}, @@ -798,4 +808,4 @@ _io_BufferedRandom___init__(PyObject *self, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=86cfa7f53e470cd9 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=1fedc6b2cd054528 input=a9049054013a1b77]*/ From 34c3e990247b1311a617109735b2670cb139c24b Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 10 May 2023 14:40:55 +0200 Subject: [PATCH 3/6] Add missing *args --- Modules/_io/bufferedio.c | 24 +++-- Modules/_io/clinic/bufferedio.c.h | 142 ++++++++++++++++++++++++------ 2 files changed, 133 insertions(+), 33 deletions(-) diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index 73e1b833991172..7592e49c2dd039 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -117,6 +117,7 @@ _io._BufferedIOBase.detach cls: defining_class / + *args: object Disconnect this buffer from its underlying raw stream and return it. @@ -125,8 +126,9 @@ state. [clinic start generated code]*/ static PyObject * -_io__BufferedIOBase_detach_impl(PyObject *self, PyTypeObject *cls) -/*[clinic end generated code: output=b87b135d67cd4448 input=0b61a7b4357c1ea7]*/ +_io__BufferedIOBase_detach_impl(PyObject *self, PyTypeObject *cls, + PyObject *args) +/*[clinic end generated code: output=f713c93ded3dd685 input=fb1ce27699f480eb]*/ { _PyIO_State *state = IO_STATE(); return bufferediobase_unsupported(state, "detach"); @@ -137,6 +139,7 @@ _io._BufferedIOBase.read cls: defining_class / + *args: object Read and return up to n bytes. @@ -157,8 +160,9 @@ mode and no data is available at the moment. [clinic start generated code]*/ static PyObject * -_io__BufferedIOBase_read_impl(PyObject *self, PyTypeObject *cls) -/*[clinic end generated code: output=905b1b6ea25c0aa5 input=52e347baff1c191c]*/ +_io__BufferedIOBase_read_impl(PyObject *self, PyTypeObject *cls, + PyObject *args) +/*[clinic end generated code: output=4521b30940fd7b67 input=7e26b448274234a0]*/ { _PyIO_State *state = IO_STATE(); return bufferediobase_unsupported(state, "read"); @@ -169,6 +173,7 @@ _io._BufferedIOBase.read1 cls: defining_class / + *args: object Read and return up to n bytes, with at most one read() call to the underlying raw stream. @@ -177,8 +182,9 @@ A short result does not imply that EOF is imminent. [clinic start generated code]*/ static PyObject * -_io__BufferedIOBase_read1_impl(PyObject *self, PyTypeObject *cls) -/*[clinic end generated code: output=999785c4a78817bf input=c38f07e1be5ee79d]*/ +_io__BufferedIOBase_read1_impl(PyObject *self, PyTypeObject *cls, + PyObject *args) +/*[clinic end generated code: output=636fd241c21e050a input=ef546a1238c5b41c]*/ { _PyIO_State *state = IO_STATE(); return bufferediobase_unsupported(state, "read1"); @@ -189,6 +195,7 @@ _io._BufferedIOBase.write cls: defining_class / + *args: object Write the given buffer to the IO stream. @@ -200,8 +207,9 @@ underlying raw stream cannot accept more data at the moment. [clinic start generated code]*/ static PyObject * -_io__BufferedIOBase_write_impl(PyObject *self, PyTypeObject *cls) -/*[clinic end generated code: output=be944cf83e6f7356 input=02b37c30f28e4882]*/ +_io__BufferedIOBase_write_impl(PyObject *self, PyTypeObject *cls, + PyObject *args) +/*[clinic end generated code: output=d51feea4bcac9892 input=f79b72c4dccb3dc2]*/ { _PyIO_State *state = IO_STATE(); return bufferediobase_unsupported(state, "write"); diff --git a/Modules/_io/clinic/bufferedio.c.h b/Modules/_io/clinic/bufferedio.c.h index 4797c39173ca16..f211b38be6337c 100644 --- a/Modules/_io/clinic/bufferedio.c.h +++ b/Modules/_io/clinic/bufferedio.c.h @@ -83,7 +83,7 @@ _io__BufferedIOBase_readinto1(PyObject *self, PyObject *arg) } PyDoc_STRVAR(_io__BufferedIOBase_detach__doc__, -"detach($self, /)\n" +"detach($self, /, *args)\n" "--\n" "\n" "Disconnect this buffer from its underlying raw stream and return it.\n" @@ -95,20 +95,43 @@ PyDoc_STRVAR(_io__BufferedIOBase_detach__doc__, {"detach", _PyCFunction_CAST(_io__BufferedIOBase_detach), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__BufferedIOBase_detach__doc__}, static PyObject * -_io__BufferedIOBase_detach_impl(PyObject *self, PyTypeObject *cls); +_io__BufferedIOBase_detach_impl(PyObject *self, PyTypeObject *cls, + PyObject *args); static PyObject * _io__BufferedIOBase_detach(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { - PyErr_SetString(PyExc_TypeError, "detach() takes no arguments"); - return NULL; + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "detach", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *__clinic_args = NULL; + + args = _PyArg_UnpackKeywordsWithVararg(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, 0, argsbuf); + if (!args) { + goto exit; } - return _io__BufferedIOBase_detach_impl(self, cls); + __clinic_args = args[0]; + return_value = _io__BufferedIOBase_detach_impl(self, cls, __clinic_args); + +exit: + Py_XDECREF(__clinic_args); + return return_value; } PyDoc_STRVAR(_io__BufferedIOBase_read__doc__, -"read($self, /)\n" +"read($self, /, *args)\n" "--\n" "\n" "Read and return up to n bytes.\n" @@ -132,20 +155,43 @@ PyDoc_STRVAR(_io__BufferedIOBase_read__doc__, {"read", _PyCFunction_CAST(_io__BufferedIOBase_read), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__BufferedIOBase_read__doc__}, static PyObject * -_io__BufferedIOBase_read_impl(PyObject *self, PyTypeObject *cls); +_io__BufferedIOBase_read_impl(PyObject *self, PyTypeObject *cls, + PyObject *args); static PyObject * _io__BufferedIOBase_read(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { - PyErr_SetString(PyExc_TypeError, "read() takes no arguments"); - return NULL; + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "read", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *__clinic_args = NULL; + + args = _PyArg_UnpackKeywordsWithVararg(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, 0, argsbuf); + if (!args) { + goto exit; } - return _io__BufferedIOBase_read_impl(self, cls); + __clinic_args = args[0]; + return_value = _io__BufferedIOBase_read_impl(self, cls, __clinic_args); + +exit: + Py_XDECREF(__clinic_args); + return return_value; } PyDoc_STRVAR(_io__BufferedIOBase_read1__doc__, -"read1($self, /)\n" +"read1($self, /, *args)\n" "--\n" "\n" "Read and return up to n bytes, with at most one read() call to the underlying raw stream.\n" @@ -157,20 +203,43 @@ PyDoc_STRVAR(_io__BufferedIOBase_read1__doc__, {"read1", _PyCFunction_CAST(_io__BufferedIOBase_read1), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__BufferedIOBase_read1__doc__}, static PyObject * -_io__BufferedIOBase_read1_impl(PyObject *self, PyTypeObject *cls); +_io__BufferedIOBase_read1_impl(PyObject *self, PyTypeObject *cls, + PyObject *args); static PyObject * _io__BufferedIOBase_read1(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { - PyErr_SetString(PyExc_TypeError, "read1() takes no arguments"); - return NULL; + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "read1", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *__clinic_args = NULL; + + args = _PyArg_UnpackKeywordsWithVararg(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, 0, argsbuf); + if (!args) { + goto exit; } - return _io__BufferedIOBase_read1_impl(self, cls); + __clinic_args = args[0]; + return_value = _io__BufferedIOBase_read1_impl(self, cls, __clinic_args); + +exit: + Py_XDECREF(__clinic_args); + return return_value; } PyDoc_STRVAR(_io__BufferedIOBase_write__doc__, -"write($self, /)\n" +"write($self, /, *args)\n" "--\n" "\n" "Write the given buffer to the IO stream.\n" @@ -185,16 +254,39 @@ PyDoc_STRVAR(_io__BufferedIOBase_write__doc__, {"write", _PyCFunction_CAST(_io__BufferedIOBase_write), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__BufferedIOBase_write__doc__}, static PyObject * -_io__BufferedIOBase_write_impl(PyObject *self, PyTypeObject *cls); +_io__BufferedIOBase_write_impl(PyObject *self, PyTypeObject *cls, + PyObject *args); static PyObject * _io__BufferedIOBase_write(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { - PyErr_SetString(PyExc_TypeError, "write() takes no arguments"); - return NULL; + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "write", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *__clinic_args = NULL; + + args = _PyArg_UnpackKeywordsWithVararg(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, 0, argsbuf); + if (!args) { + goto exit; } - return _io__BufferedIOBase_write_impl(self, cls); + __clinic_args = args[0]; + return_value = _io__BufferedIOBase_write_impl(self, cls, __clinic_args); + +exit: + Py_XDECREF(__clinic_args); + return return_value; } PyDoc_STRVAR(_io__Buffered_peek__doc__, @@ -808,4 +900,4 @@ _io_BufferedRandom___init__(PyObject *self, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=1fedc6b2cd054528 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b32416f845f6a9a5 input=a9049054013a1b77]*/ From 7c785b34a66ef4600970dedbdf0b00798b142069 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 10 May 2023 14:42:00 +0200 Subject: [PATCH 4/6] ..but not detach() --- Modules/_io/bufferedio.c | 6 ++--- Modules/_io/clinic/bufferedio.c.h | 37 ++++++------------------------- 2 files changed, 9 insertions(+), 34 deletions(-) diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index 7592e49c2dd039..e84e15cd102d6f 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -117,7 +117,6 @@ _io._BufferedIOBase.detach cls: defining_class / - *args: object Disconnect this buffer from its underlying raw stream and return it. @@ -126,9 +125,8 @@ state. [clinic start generated code]*/ static PyObject * -_io__BufferedIOBase_detach_impl(PyObject *self, PyTypeObject *cls, - PyObject *args) -/*[clinic end generated code: output=f713c93ded3dd685 input=fb1ce27699f480eb]*/ +_io__BufferedIOBase_detach_impl(PyObject *self, PyTypeObject *cls) +/*[clinic end generated code: output=b87b135d67cd4448 input=0b61a7b4357c1ea7]*/ { _PyIO_State *state = IO_STATE(); return bufferediobase_unsupported(state, "detach"); diff --git a/Modules/_io/clinic/bufferedio.c.h b/Modules/_io/clinic/bufferedio.c.h index f211b38be6337c..a7ac23ad952fbb 100644 --- a/Modules/_io/clinic/bufferedio.c.h +++ b/Modules/_io/clinic/bufferedio.c.h @@ -83,7 +83,7 @@ _io__BufferedIOBase_readinto1(PyObject *self, PyObject *arg) } PyDoc_STRVAR(_io__BufferedIOBase_detach__doc__, -"detach($self, /, *args)\n" +"detach($self, /)\n" "--\n" "\n" "Disconnect this buffer from its underlying raw stream and return it.\n" @@ -95,39 +95,16 @@ PyDoc_STRVAR(_io__BufferedIOBase_detach__doc__, {"detach", _PyCFunction_CAST(_io__BufferedIOBase_detach), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__BufferedIOBase_detach__doc__}, static PyObject * -_io__BufferedIOBase_detach_impl(PyObject *self, PyTypeObject *cls, - PyObject *args); +_io__BufferedIOBase_detach_impl(PyObject *self, PyTypeObject *cls); static PyObject * _io__BufferedIOBase_detach(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - #else - # define KWTUPLE NULL - #endif - - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = { - .keywords = _keywords, - .fname = "detach", - .kwtuple = KWTUPLE, - }; - #undef KWTUPLE - PyObject *argsbuf[1]; - PyObject *__clinic_args = NULL; - - args = _PyArg_UnpackKeywordsWithVararg(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, 0, argsbuf); - if (!args) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "detach() takes no arguments"); + return NULL; } - __clinic_args = args[0]; - return_value = _io__BufferedIOBase_detach_impl(self, cls, __clinic_args); - -exit: - Py_XDECREF(__clinic_args); - return return_value; + return _io__BufferedIOBase_detach_impl(self, cls); } PyDoc_STRVAR(_io__BufferedIOBase_read__doc__, @@ -900,4 +877,4 @@ _io_BufferedRandom___init__(PyObject *self, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=b32416f845f6a9a5 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a9f3647aef80aa5c input=a9049054013a1b77]*/ From 28fc57ea0999822a8d251c8acafdef1fb42abffa Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 10 May 2023 14:47:43 +0200 Subject: [PATCH 5/6] Use consistent mood, since we're touching this anyways --- Modules/_io/bufferedio.c | 6 +++--- Modules/_io/clinic/bufferedio.c.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index e84e15cd102d6f..e50f92f2144acb 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -141,8 +141,8 @@ _io._BufferedIOBase.read Read and return up to n bytes. -If the argument is omitted, None, or negative, reads and -returns all data until EOF +If the argument is omitted, None, or negative, read and +return all data until EOF If the argument is positive, and the underlying raw stream is not 'interactive', multiple raw reads may be issued to satisfy @@ -160,7 +160,7 @@ mode and no data is available at the moment. static PyObject * _io__BufferedIOBase_read_impl(PyObject *self, PyTypeObject *cls, PyObject *args) -/*[clinic end generated code: output=4521b30940fd7b67 input=7e26b448274234a0]*/ +/*[clinic end generated code: output=4521b30940fd7b67 input=83f4490585256485]*/ { _PyIO_State *state = IO_STATE(); return bufferediobase_unsupported(state, "read"); diff --git a/Modules/_io/clinic/bufferedio.c.h b/Modules/_io/clinic/bufferedio.c.h index a7ac23ad952fbb..efd9f1df015e2f 100644 --- a/Modules/_io/clinic/bufferedio.c.h +++ b/Modules/_io/clinic/bufferedio.c.h @@ -113,8 +113,8 @@ PyDoc_STRVAR(_io__BufferedIOBase_read__doc__, "\n" "Read and return up to n bytes.\n" "\n" -"If the argument is omitted, None, or negative, reads and\n" -"returns all data until EOF\n" +"If the argument is omitted, None, or negative, read and\n" +"return all data until EOF\n" "\n" "If the argument is positive, and the underlying raw stream is\n" "not \'interactive\', multiple raw reads may be issued to satisfy\n" @@ -877,4 +877,4 @@ _io_BufferedRandom___init__(PyObject *self, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=a9f3647aef80aa5c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=e9f0d997b78ca1ec input=a9049054013a1b77]*/ From 940db40899e984a67c8abb05d83aaaee684a0b13 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 10 May 2023 15:50:26 +0200 Subject: [PATCH 6/6] Address docstring review --- Modules/_io/bufferedio.c | 6 +++--- Modules/_io/clinic/bufferedio.c.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index e50f92f2144acb..c7ae60281c2f58 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -142,12 +142,12 @@ _io._BufferedIOBase.read Read and return up to n bytes. If the argument is omitted, None, or negative, read and -return all data until EOF +return all data until EOF. If the argument is positive, and the underlying raw stream is not 'interactive', multiple raw reads may be issued to satisfy the byte count (unless EOF is reached first). -But for interactive raw streams (as well as sockets and pipes), +However, for interactive raw streams (as well as sockets and pipes), at most one raw read will be issued, and a short result does not imply that EOF is imminent. @@ -160,7 +160,7 @@ mode and no data is available at the moment. static PyObject * _io__BufferedIOBase_read_impl(PyObject *self, PyTypeObject *cls, PyObject *args) -/*[clinic end generated code: output=4521b30940fd7b67 input=83f4490585256485]*/ +/*[clinic end generated code: output=4521b30940fd7b67 input=390205758adc8510]*/ { _PyIO_State *state = IO_STATE(); return bufferediobase_unsupported(state, "read"); diff --git a/Modules/_io/clinic/bufferedio.c.h b/Modules/_io/clinic/bufferedio.c.h index efd9f1df015e2f..a898b01899babe 100644 --- a/Modules/_io/clinic/bufferedio.c.h +++ b/Modules/_io/clinic/bufferedio.c.h @@ -114,12 +114,12 @@ PyDoc_STRVAR(_io__BufferedIOBase_read__doc__, "Read and return up to n bytes.\n" "\n" "If the argument is omitted, None, or negative, read and\n" -"return all data until EOF\n" +"return all data until EOF.\n" "\n" "If the argument is positive, and the underlying raw stream is\n" "not \'interactive\', multiple raw reads may be issued to satisfy\n" "the byte count (unless EOF is reached first).\n" -"But for interactive raw streams (as well as sockets and pipes),\n" +"However, for interactive raw streams (as well as sockets and pipes),\n" "at most one raw read will be issued, and a short result does not\n" "imply that EOF is imminent.\n" "\n" @@ -877,4 +877,4 @@ _io_BufferedRandom___init__(PyObject *self, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=e9f0d997b78ca1ec input=a9049054013a1b77]*/ +/*[clinic end generated code: output=c4ea041ccc91b5d2 input=a9049054013a1b77]*/