[Python-checkins] gh-101819: Fix _io clinic input for unused base class method stubs (#104418)

erlend-aasland webhook-mailer at python.org
Mon May 15 07:22:13 EDT 2023


https://github.com/python/cpython/commit/b378d991f8cd41c33416e590cb83472cce1d6b98
commit: b378d991f8cd41c33416e590cb83472cce1d6b98
branch: main
author: Erlend E. Aasland <erlend.aasland at protonmail.com>
committer: erlend-aasland <erlend.aasland at protonmail.com>
date: 2023-05-15T13:21:38+02:00
summary:

gh-101819: Fix _io clinic input for unused base class method stubs (#104418)

When preparing the _io extension module for isolation, many methods were
adapted to Argument Clinic. Some of these used the '*args: object'
signature, which is incorrect. These are now corrected to an exact
signature, and marked unused, since they are stub methods.

files:
M Modules/_io/bufferedio.c
M Modules/_io/clinic/bufferedio.c.h
M Modules/_io/clinic/iobase.c.h
M Modules/_io/clinic/textio.c.h
M Modules/_io/iobase.c
M Modules/_io/textio.c

diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c
index d5cc047bd8d5..6f291c344960 100644
--- a/Modules/_io/bufferedio.c
+++ b/Modules/_io/bufferedio.c
@@ -136,15 +136,15 @@ _io__BufferedIOBase_detach_impl(PyObject *self, PyTypeObject *cls)
 _io._BufferedIOBase.read
 
     cls: defining_class
+    size: int(unused=True) = -1
     /
-    *args: object
 
 Read and return up to n bytes.
 
-If the argument is omitted, None, or negative, read and
+If the size argument is omitted, None, or negative, read and
 return all data until EOF.
 
-If the argument is positive, and the underlying raw stream is
+If the size 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).
 However, for interactive raw streams (as well as sockets and pipes),
@@ -159,8 +159,8 @@ 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=390205758adc8510]*/
+                              int Py_UNUSED(size))
+/*[clinic end generated code: output=aceb2765587b0a29 input=824f6f910465e61a]*/
 {
     _PyIO_State *state = get_io_state_by_cls(cls);
     return bufferediobase_unsupported(state, "read");
@@ -170,10 +170,10 @@ _io__BufferedIOBase_read_impl(PyObject *self, PyTypeObject *cls,
 _io._BufferedIOBase.read1
 
     cls: defining_class
+    size: int(unused=True) = -1
     /
-    *args: object
 
-Read and return up to n bytes, with at most one read() call to the underlying raw stream.
+Read and return up to size 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.
@@ -181,8 +181,8 @@ A short result does not imply that EOF is imminent.
 
 static PyObject *
 _io__BufferedIOBase_read1_impl(PyObject *self, PyTypeObject *cls,
-                               PyObject *args)
-/*[clinic end generated code: output=636fd241c21e050a input=ef546a1238c5b41c]*/
+                               int Py_UNUSED(size))
+/*[clinic end generated code: output=2e7fc62972487eaa input=af76380e020fd9e6]*/
 {
     _PyIO_State *state = get_io_state_by_cls(cls);
     return bufferediobase_unsupported(state, "read1");
@@ -192,10 +192,10 @@ _io__BufferedIOBase_read1_impl(PyObject *self, PyTypeObject *cls,
 _io._BufferedIOBase.write
 
     cls: defining_class
+    b: object(unused=True)
     /
-    *args: object
 
-Write the given buffer to the IO stream.
+Write buffer b to the IO stream.
 
 Return the number of bytes written, which is always
 the length of b in bytes.
@@ -206,8 +206,8 @@ underlying raw stream cannot accept more data at the moment.
 
 static PyObject *
 _io__BufferedIOBase_write_impl(PyObject *self, PyTypeObject *cls,
-                               PyObject *args)
-/*[clinic end generated code: output=d51feea4bcac9892 input=f79b72c4dccb3dc2]*/
+                               PyObject *Py_UNUSED(b))
+/*[clinic end generated code: output=712c635246bf2306 input=9793f5c8f71029ad]*/
 {
     _PyIO_State *state = get_io_state_by_cls(cls);
     return bufferediobase_unsupported(state, "write");
diff --git a/Modules/_io/clinic/bufferedio.c.h b/Modules/_io/clinic/bufferedio.c.h
index e2ac90c54a10..4f40fdadf8ec 100644
--- a/Modules/_io/clinic/bufferedio.c.h
+++ b/Modules/_io/clinic/bufferedio.c.h
@@ -108,15 +108,15 @@ _io__BufferedIOBase_detach(PyObject *self, PyTypeObject *cls, PyObject *const *a
 }
 
 PyDoc_STRVAR(_io__BufferedIOBase_read__doc__,
-"read($self, /, *args)\n"
+"read($self, size=-1, /)\n"
 "--\n"
 "\n"
 "Read and return up to n bytes.\n"
 "\n"
-"If the argument is omitted, None, or negative, read and\n"
+"If the size 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"
+"If the size 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"
 "However, for interactive raw streams (as well as sockets and pipes),\n"
@@ -133,7 +133,7 @@ PyDoc_STRVAR(_io__BufferedIOBase_read__doc__,
 
 static PyObject *
 _io__BufferedIOBase_read_impl(PyObject *self, PyTypeObject *cls,
-                              PyObject *args);
+                              int Py_UNUSED(size));
 
 static PyObject *
 _io__BufferedIOBase_read(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
@@ -145,7 +145,7 @@ _io__BufferedIOBase_read(PyObject *self, PyTypeObject *cls, PyObject *const *arg
     #  define KWTUPLE NULL
     #endif
 
-    static const char * const _keywords[] = { NULL};
+    static const char * const _keywords[] = {"", NULL};
     static _PyArg_Parser _parser = {
         .keywords = _keywords,
         .fname = "read",
@@ -153,25 +153,31 @@ _io__BufferedIOBase_read(PyObject *self, PyTypeObject *cls, PyObject *const *arg
     };
     #undef KWTUPLE
     PyObject *argsbuf[1];
-    PyObject *__clinic_args = NULL;
+    int size = -1;
 
-    args = _PyArg_UnpackKeywordsWithVararg(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, 0, argsbuf);
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf);
     if (!args) {
         goto exit;
     }
-    __clinic_args = args[0];
-    return_value = _io__BufferedIOBase_read_impl(self, cls, __clinic_args);
+    if (nargs < 1) {
+        goto skip_optional_posonly;
+    }
+    size = _PyLong_AsInt(args[0]);
+    if (size == -1 && PyErr_Occurred()) {
+        goto exit;
+    }
+skip_optional_posonly:
+    return_value = _io__BufferedIOBase_read_impl(self, cls, size);
 
 exit:
-    Py_XDECREF(__clinic_args);
     return return_value;
 }
 
 PyDoc_STRVAR(_io__BufferedIOBase_read1__doc__,
-"read1($self, /, *args)\n"
+"read1($self, size=-1, /)\n"
 "--\n"
 "\n"
-"Read and return up to n bytes, with at most one read() call to the underlying raw stream.\n"
+"Read and return up to size bytes, with at most one read() call to the underlying raw stream.\n"
 "\n"
 "Return an empty bytes object on EOF.\n"
 "A short result does not imply that EOF is imminent.");
@@ -181,7 +187,7 @@ PyDoc_STRVAR(_io__BufferedIOBase_read1__doc__,
 
 static PyObject *
 _io__BufferedIOBase_read1_impl(PyObject *self, PyTypeObject *cls,
-                               PyObject *args);
+                               int Py_UNUSED(size));
 
 static PyObject *
 _io__BufferedIOBase_read1(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
@@ -193,7 +199,7 @@ _io__BufferedIOBase_read1(PyObject *self, PyTypeObject *cls, PyObject *const *ar
     #  define KWTUPLE NULL
     #endif
 
-    static const char * const _keywords[] = { NULL};
+    static const char * const _keywords[] = {"", NULL};
     static _PyArg_Parser _parser = {
         .keywords = _keywords,
         .fname = "read1",
@@ -201,25 +207,31 @@ _io__BufferedIOBase_read1(PyObject *self, PyTypeObject *cls, PyObject *const *ar
     };
     #undef KWTUPLE
     PyObject *argsbuf[1];
-    PyObject *__clinic_args = NULL;
+    int size = -1;
 
-    args = _PyArg_UnpackKeywordsWithVararg(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, 0, argsbuf);
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf);
     if (!args) {
         goto exit;
     }
-    __clinic_args = args[0];
-    return_value = _io__BufferedIOBase_read1_impl(self, cls, __clinic_args);
+    if (nargs < 1) {
+        goto skip_optional_posonly;
+    }
+    size = _PyLong_AsInt(args[0]);
+    if (size == -1 && PyErr_Occurred()) {
+        goto exit;
+    }
+skip_optional_posonly:
+    return_value = _io__BufferedIOBase_read1_impl(self, cls, size);
 
 exit:
-    Py_XDECREF(__clinic_args);
     return return_value;
 }
 
 PyDoc_STRVAR(_io__BufferedIOBase_write__doc__,
-"write($self, /, *args)\n"
+"write($self, b, /)\n"
 "--\n"
 "\n"
-"Write the given buffer to the IO stream.\n"
+"Write buffer b to the IO stream.\n"
 "\n"
 "Return the number of bytes written, which is always\n"
 "the length of b in bytes.\n"
@@ -232,7 +244,7 @@ PyDoc_STRVAR(_io__BufferedIOBase_write__doc__,
 
 static PyObject *
 _io__BufferedIOBase_write_impl(PyObject *self, PyTypeObject *cls,
-                               PyObject *args);
+                               PyObject *Py_UNUSED(b));
 
 static PyObject *
 _io__BufferedIOBase_write(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
@@ -244,7 +256,7 @@ _io__BufferedIOBase_write(PyObject *self, PyTypeObject *cls, PyObject *const *ar
     #  define KWTUPLE NULL
     #endif
 
-    static const char * const _keywords[] = { NULL};
+    static const char * const _keywords[] = {"", NULL};
     static _PyArg_Parser _parser = {
         .keywords = _keywords,
         .fname = "write",
@@ -252,17 +264,16 @@ _io__BufferedIOBase_write(PyObject *self, PyTypeObject *cls, PyObject *const *ar
     };
     #undef KWTUPLE
     PyObject *argsbuf[1];
-    PyObject *__clinic_args = NULL;
+    PyObject *b;
 
-    args = _PyArg_UnpackKeywordsWithVararg(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, 0, argsbuf);
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
     if (!args) {
         goto exit;
     }
-    __clinic_args = args[0];
-    return_value = _io__BufferedIOBase_write_impl(self, cls, __clinic_args);
+    b = args[0];
+    return_value = _io__BufferedIOBase_write_impl(self, cls, b);
 
 exit:
-    Py_XDECREF(__clinic_args);
     return return_value;
 }
 
@@ -1087,4 +1098,4 @@ _io_BufferedRandom___init__(PyObject *self, PyObject *args, PyObject *kwargs)
 exit:
     return return_value;
 }
-/*[clinic end generated code: output=d770e392e8702e12 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=b7ddf84a5bc2bf34 input=a9049054013a1b77]*/
diff --git a/Modules/_io/clinic/iobase.c.h b/Modules/_io/clinic/iobase.c.h
index 7e6b3b5b78e8..773e00104770 100644
--- a/Modules/_io/clinic/iobase.c.h
+++ b/Modules/_io/clinic/iobase.c.h
@@ -9,7 +9,7 @@ preserve
 
 
 PyDoc_STRVAR(_io__IOBase_seek__doc__,
-"seek($self, /, *args)\n"
+"seek($self, offset, whence=os.SEEK_SET, /)\n"
 "--\n"
 "\n"
 "Change the stream position to the given byte offset.\n"
@@ -17,9 +17,9 @@ PyDoc_STRVAR(_io__IOBase_seek__doc__,
 "The offset is interpreted relative to the position indicated by whence.\n"
 "Values for whence are:\n"
 "\n"
-"* 0 -- start of stream (the default); offset should be zero or positive\n"
-"* 1 -- current stream position; offset may be negative\n"
-"* 2 -- end of stream; offset is usually negative\n"
+"* os.SEEK_SET or 0 -- start of stream (the default); offset should be zero or positive\n"
+"* os.SEEK_CUR or 1 -- current stream position; offset may be negative\n"
+"* os.SEEK_END or 2 -- end of stream; offset is usually negative\n"
 "\n"
 "Return the new absolute position.");
 
@@ -27,7 +27,8 @@ PyDoc_STRVAR(_io__IOBase_seek__doc__,
     {"seek", _PyCFunction_CAST(_io__IOBase_seek), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__IOBase_seek__doc__},
 
 static PyObject *
-_io__IOBase_seek_impl(PyObject *self, PyTypeObject *cls, PyObject *args);
+_io__IOBase_seek_impl(PyObject *self, PyTypeObject *cls,
+                      int Py_UNUSED(offset), int Py_UNUSED(whence));
 
 static PyObject *
 _io__IOBase_seek(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
@@ -39,25 +40,36 @@ _io__IOBase_seek(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ss
     #  define KWTUPLE NULL
     #endif
 
-    static const char * const _keywords[] = { NULL};
+    static const char * const _keywords[] = {"", "", NULL};
     static _PyArg_Parser _parser = {
         .keywords = _keywords,
         .fname = "seek",
         .kwtuple = KWTUPLE,
     };
     #undef KWTUPLE
-    PyObject *argsbuf[1];
-    PyObject *__clinic_args = NULL;
+    PyObject *argsbuf[2];
+    int offset;
+    int whence = 0;
 
-    args = _PyArg_UnpackKeywordsWithVararg(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, 0, argsbuf);
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf);
     if (!args) {
         goto exit;
     }
-    __clinic_args = args[0];
-    return_value = _io__IOBase_seek_impl(self, cls, __clinic_args);
+    offset = _PyLong_AsInt(args[0]);
+    if (offset == -1 && PyErr_Occurred()) {
+        goto exit;
+    }
+    if (nargs < 2) {
+        goto skip_optional_posonly;
+    }
+    whence = _PyLong_AsInt(args[1]);
+    if (whence == -1 && PyErr_Occurred()) {
+        goto exit;
+    }
+skip_optional_posonly:
+    return_value = _io__IOBase_seek_impl(self, cls, offset, whence);
 
 exit:
-    Py_XDECREF(__clinic_args);
     return return_value;
 }
 
@@ -80,7 +92,7 @@ _io__IOBase_tell(PyObject *self, PyObject *Py_UNUSED(ignored))
 }
 
 PyDoc_STRVAR(_io__IOBase_truncate__doc__,
-"truncate($self, /, *args)\n"
+"truncate($self, size=None, /)\n"
 "--\n"
 "\n"
 "Truncate file to size bytes.\n"
@@ -92,7 +104,8 @@ PyDoc_STRVAR(_io__IOBase_truncate__doc__,
     {"truncate", _PyCFunction_CAST(_io__IOBase_truncate), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__IOBase_truncate__doc__},
 
 static PyObject *
-_io__IOBase_truncate_impl(PyObject *self, PyTypeObject *cls, PyObject *args);
+_io__IOBase_truncate_impl(PyObject *self, PyTypeObject *cls,
+                          PyObject *Py_UNUSED(size));
 
 static PyObject *
 _io__IOBase_truncate(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
@@ -104,7 +117,7 @@ _io__IOBase_truncate(PyObject *self, PyTypeObject *cls, PyObject *const *args, P
     #  define KWTUPLE NULL
     #endif
 
-    static const char * const _keywords[] = { NULL};
+    static const char * const _keywords[] = {"", NULL};
     static _PyArg_Parser _parser = {
         .keywords = _keywords,
         .fname = "truncate",
@@ -112,17 +125,20 @@ _io__IOBase_truncate(PyObject *self, PyTypeObject *cls, PyObject *const *args, P
     };
     #undef KWTUPLE
     PyObject *argsbuf[1];
-    PyObject *__clinic_args = NULL;
+    PyObject *size = Py_None;
 
-    args = _PyArg_UnpackKeywordsWithVararg(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, 0, argsbuf);
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf);
     if (!args) {
         goto exit;
     }
-    __clinic_args = args[0];
-    return_value = _io__IOBase_truncate_impl(self, cls, __clinic_args);
+    if (nargs < 1) {
+        goto skip_optional_posonly;
+    }
+    size = args[0];
+skip_optional_posonly:
+    return_value = _io__IOBase_truncate_impl(self, cls, size);
 
 exit:
-    Py_XDECREF(__clinic_args);
     return return_value;
 }
 
@@ -420,4 +436,4 @@ _io__RawIOBase_readall(PyObject *self, PyObject *Py_UNUSED(ignored))
 {
     return _io__RawIOBase_readall_impl(self);
 }
-/*[clinic end generated code: output=63bc25a5bfcecaf0 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=301b22f8f75ce3dc input=a9049054013a1b77]*/
diff --git a/Modules/_io/clinic/textio.c.h b/Modules/_io/clinic/textio.c.h
index 01965013ec6a..33fc23bd4c0c 100644
--- a/Modules/_io/clinic/textio.c.h
+++ b/Modules/_io/clinic/textio.c.h
@@ -33,7 +33,7 @@ _io__TextIOBase_detach(PyObject *self, PyTypeObject *cls, PyObject *const *args,
 }
 
 PyDoc_STRVAR(_io__TextIOBase_read__doc__,
-"read($self, /, *args)\n"
+"read($self, size=-1, /)\n"
 "--\n"
 "\n"
 "Read at most size characters from stream.\n"
@@ -45,7 +45,8 @@ PyDoc_STRVAR(_io__TextIOBase_read__doc__,
     {"read", _PyCFunction_CAST(_io__TextIOBase_read), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__TextIOBase_read__doc__},
 
 static PyObject *
-_io__TextIOBase_read_impl(PyObject *self, PyTypeObject *cls, PyObject *args);
+_io__TextIOBase_read_impl(PyObject *self, PyTypeObject *cls,
+                          int Py_UNUSED(size));
 
 static PyObject *
 _io__TextIOBase_read(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
@@ -57,7 +58,7 @@ _io__TextIOBase_read(PyObject *self, PyTypeObject *cls, PyObject *const *args, P
     #  define KWTUPLE NULL
     #endif
 
-    static const char * const _keywords[] = { NULL};
+    static const char * const _keywords[] = {"", NULL};
     static _PyArg_Parser _parser = {
         .keywords = _keywords,
         .fname = "read",
@@ -65,34 +66,41 @@ _io__TextIOBase_read(PyObject *self, PyTypeObject *cls, PyObject *const *args, P
     };
     #undef KWTUPLE
     PyObject *argsbuf[1];
-    PyObject *__clinic_args = NULL;
+    int size = -1;
 
-    args = _PyArg_UnpackKeywordsWithVararg(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, 0, argsbuf);
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf);
     if (!args) {
         goto exit;
     }
-    __clinic_args = args[0];
-    return_value = _io__TextIOBase_read_impl(self, cls, __clinic_args);
+    if (nargs < 1) {
+        goto skip_optional_posonly;
+    }
+    size = _PyLong_AsInt(args[0]);
+    if (size == -1 && PyErr_Occurred()) {
+        goto exit;
+    }
+skip_optional_posonly:
+    return_value = _io__TextIOBase_read_impl(self, cls, size);
 
 exit:
-    Py_XDECREF(__clinic_args);
     return return_value;
 }
 
 PyDoc_STRVAR(_io__TextIOBase_readline__doc__,
-"readline($self, /, *args)\n"
+"readline($self, size=-1, /)\n"
 "--\n"
 "\n"
 "Read until newline or EOF.\n"
 "\n"
-"Return an empty string if EOF is hit immediately.");
+"Return an empty string if EOF is hit immediately.\n"
+"If size is specified, at most size characters will be read.");
 
 #define _IO__TEXTIOBASE_READLINE_METHODDEF    \
     {"readline", _PyCFunction_CAST(_io__TextIOBase_readline), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__TextIOBase_readline__doc__},
 
 static PyObject *
 _io__TextIOBase_readline_impl(PyObject *self, PyTypeObject *cls,
-                              PyObject *args);
+                              int Py_UNUSED(size));
 
 static PyObject *
 _io__TextIOBase_readline(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
@@ -104,7 +112,7 @@ _io__TextIOBase_readline(PyObject *self, PyTypeObject *cls, PyObject *const *arg
     #  define KWTUPLE NULL
     #endif
 
-    static const char * const _keywords[] = { NULL};
+    static const char * const _keywords[] = {"", NULL};
     static _PyArg_Parser _parser = {
         .keywords = _keywords,
         .fname = "readline",
@@ -112,25 +120,31 @@ _io__TextIOBase_readline(PyObject *self, PyTypeObject *cls, PyObject *const *arg
     };
     #undef KWTUPLE
     PyObject *argsbuf[1];
-    PyObject *__clinic_args = NULL;
+    int size = -1;
 
-    args = _PyArg_UnpackKeywordsWithVararg(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, 0, argsbuf);
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf);
     if (!args) {
         goto exit;
     }
-    __clinic_args = args[0];
-    return_value = _io__TextIOBase_readline_impl(self, cls, __clinic_args);
+    if (nargs < 1) {
+        goto skip_optional_posonly;
+    }
+    size = _PyLong_AsInt(args[0]);
+    if (size == -1 && PyErr_Occurred()) {
+        goto exit;
+    }
+skip_optional_posonly:
+    return_value = _io__TextIOBase_readline_impl(self, cls, size);
 
 exit:
-    Py_XDECREF(__clinic_args);
     return return_value;
 }
 
 PyDoc_STRVAR(_io__TextIOBase_write__doc__,
-"write($self, /, *args)\n"
+"write($self, s, /)\n"
 "--\n"
 "\n"
-"Write string to stream.\n"
+"Write string s to stream.\n"
 "\n"
 "Return the number of characters written\n"
 "(which is always equal to the length of the string).");
@@ -139,7 +153,8 @@ PyDoc_STRVAR(_io__TextIOBase_write__doc__,
     {"write", _PyCFunction_CAST(_io__TextIOBase_write), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__TextIOBase_write__doc__},
 
 static PyObject *
-_io__TextIOBase_write_impl(PyObject *self, PyTypeObject *cls, PyObject *args);
+_io__TextIOBase_write_impl(PyObject *self, PyTypeObject *cls,
+                           const char *Py_UNUSED(s));
 
 static PyObject *
 _io__TextIOBase_write(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
@@ -151,7 +166,7 @@ _io__TextIOBase_write(PyObject *self, PyTypeObject *cls, PyObject *const *args,
     #  define KWTUPLE NULL
     #endif
 
-    static const char * const _keywords[] = { NULL};
+    static const char * const _keywords[] = {"", NULL};
     static _PyArg_Parser _parser = {
         .keywords = _keywords,
         .fname = "write",
@@ -159,17 +174,28 @@ _io__TextIOBase_write(PyObject *self, PyTypeObject *cls, PyObject *const *args,
     };
     #undef KWTUPLE
     PyObject *argsbuf[1];
-    PyObject *__clinic_args = NULL;
+    const char *s;
 
-    args = _PyArg_UnpackKeywordsWithVararg(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, 0, argsbuf);
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
     if (!args) {
         goto exit;
     }
-    __clinic_args = args[0];
-    return_value = _io__TextIOBase_write_impl(self, cls, __clinic_args);
+    if (!PyUnicode_Check(args[0])) {
+        _PyArg_BadArgument("write", "argument 1", "str", args[0]);
+        goto exit;
+    }
+    Py_ssize_t s_length;
+    s = PyUnicode_AsUTF8AndSize(args[0], &s_length);
+    if (s == NULL) {
+        goto exit;
+    }
+    if (strlen(s) != (size_t)s_length) {
+        PyErr_SetString(PyExc_ValueError, "embedded null character");
+        goto exit;
+    }
+    return_value = _io__TextIOBase_write_impl(self, cls, s);
 
 exit:
-    Py_XDECREF(__clinic_args);
     return return_value;
 }
 
@@ -934,4 +960,4 @@ _io_TextIOWrapper_close(textio *self, PyObject *Py_UNUSED(ignored))
 {
     return _io_TextIOWrapper_close_impl(self);
 }
-/*[clinic end generated code: output=d800e5a8a50d6720 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=42f592331302973f input=a9049054013a1b77]*/
diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c
index 764c5fb33200..14d48813aefe 100644
--- a/Modules/_io/iobase.c
+++ b/Modules/_io/iobase.c
@@ -82,24 +82,26 @@ iobase_unsupported(_PyIO_State *state, const char *message)
 /*[clinic input]
 _io._IOBase.seek
     cls: defining_class
+    offset: int(unused=True)
+    whence: int(unused=True, c_default='0') = os.SEEK_SET
     /
-    *args: object
 
 Change the stream position to the given byte offset.
 
 The offset is interpreted relative to the position indicated by whence.
 Values for whence are:
 
-* 0 -- start of stream (the default); offset should be zero or positive
-* 1 -- current stream position; offset may be negative
-* 2 -- end of stream; offset is usually negative
+* os.SEEK_SET or 0 -- start of stream (the default); offset should be zero or positive
+* os.SEEK_CUR or 1 -- current stream position; offset may be negative
+* os.SEEK_END or 2 -- end of stream; offset is usually negative
 
 Return the new absolute position.
 [clinic start generated code]*/
 
 static PyObject *
-_io__IOBase_seek_impl(PyObject *self, PyTypeObject *cls, PyObject *args)
-/*[clinic end generated code: output=1dd694ac9de260fa input=ebb5476eb22fc5d4]*/
+_io__IOBase_seek_impl(PyObject *self, PyTypeObject *cls,
+                      int Py_UNUSED(offset), int Py_UNUSED(whence))
+/*[clinic end generated code: output=8bd74ea6538ded53 input=8d4e6adcd08292f2]*/
 {
     _PyIO_State *state = get_io_state_by_cls(cls);
     return iobase_unsupported(state, "seek");
@@ -121,8 +123,8 @@ _io__IOBase_tell_impl(PyObject *self)
 /*[clinic input]
 _io._IOBase.truncate
     cls: defining_class
+    size: object(unused=True) = None
     /
-    *args: object
 
 Truncate file to size bytes.
 
@@ -131,8 +133,9 @@ as reported by tell(). Return the new size.
 [clinic start generated code]*/
 
 static PyObject *
-_io__IOBase_truncate_impl(PyObject *self, PyTypeObject *cls, PyObject *args)
-/*[clinic end generated code: output=b7eed4649cbe22c1 input=ad90582a1d8b5cc9]*/
+_io__IOBase_truncate_impl(PyObject *self, PyTypeObject *cls,
+                          PyObject *Py_UNUSED(size))
+/*[clinic end generated code: output=2013179bff1fe8ef input=660ac20936612c27]*/
 {
     _PyIO_State *state = get_io_state_by_cls(cls);
     return iobase_unsupported(state, "truncate");
diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c
index 81dd3bed005a..e858a1fb498f 100644
--- a/Modules/_io/textio.c
+++ b/Modules/_io/textio.c
@@ -69,8 +69,8 @@ _io__TextIOBase_detach_impl(PyObject *self, PyTypeObject *cls)
 /*[clinic input]
 _io._TextIOBase.read
     cls: defining_class
+    size: int(unused=True) = -1
     /
-    *args: object
 
 Read at most size characters from stream.
 
@@ -79,8 +79,9 @@ If size is negative or omitted, read until EOF.
 [clinic start generated code]*/
 
 static PyObject *
-_io__TextIOBase_read_impl(PyObject *self, PyTypeObject *cls, PyObject *args)
-/*[clinic end generated code: output=3adf28998831f461 input=cee1e84664a20de0]*/
+_io__TextIOBase_read_impl(PyObject *self, PyTypeObject *cls,
+                          int Py_UNUSED(size))
+/*[clinic end generated code: output=51a5178a309ce647 input=f5e37720f9fc563f]*/
 {
     _PyIO_State *state = get_io_state_by_cls(cls);
     return _unsupported(state, "read");
@@ -89,18 +90,19 @@ _io__TextIOBase_read_impl(PyObject *self, PyTypeObject *cls, PyObject *args)
 /*[clinic input]
 _io._TextIOBase.readline
     cls: defining_class
+    size: int(unused=True) = -1
     /
-    *args: object
 
 Read until newline or EOF.
 
 Return an empty string if EOF is hit immediately.
+If size is specified, at most size characters will be read.
 [clinic start generated code]*/
 
 static PyObject *
 _io__TextIOBase_readline_impl(PyObject *self, PyTypeObject *cls,
-                              PyObject *args)
-/*[clinic end generated code: output=3073a948d02319f3 input=58f801259f7ff3ef]*/
+                              int Py_UNUSED(size))
+/*[clinic end generated code: output=3f47d7966d6d074e input=42eafec94107fa27]*/
 {
     _PyIO_State *state = get_io_state_by_cls(cls);
     return _unsupported(state, "readline");
@@ -109,18 +111,19 @@ _io__TextIOBase_readline_impl(PyObject *self, PyTypeObject *cls,
 /*[clinic input]
 _io._TextIOBase.write
     cls: defining_class
+    s: str(unused=True)
     /
-    *args: object
 
-Write string to stream.
+Write string s to stream.
 
 Return the number of characters written
 (which is always equal to the length of the string).
 [clinic start generated code]*/
 
 static PyObject *
-_io__TextIOBase_write_impl(PyObject *self, PyTypeObject *cls, PyObject *args)
-/*[clinic end generated code: output=5d985eb529472bc4 input=21b6961b5cba9496]*/
+_io__TextIOBase_write_impl(PyObject *self, PyTypeObject *cls,
+                           const char *Py_UNUSED(s))
+/*[clinic end generated code: output=18b28231460275de input=e9cabaa5f6732b07]*/
 {
     _PyIO_State *state = get_io_state_by_cls(cls);
     return _unsupported(state, "write");



More information about the Python-checkins mailing list