Issue #23214: Implement optional BufferedReader, BytesIO read1() argument
diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c
index cbe7425..c760522 100644
--- a/Modules/_io/bufferedio.c
+++ b/Modules/_io/bufferedio.c
@@ -904,7 +904,7 @@
     CHECK_INITIALIZED(self)
     if (n < -1) {
         PyErr_SetString(PyExc_ValueError,
-                        "read length must be positive or -1");
+                        "read length must be non-negative or -1");
         return NULL;
     }
 
@@ -932,22 +932,20 @@
 
 /*[clinic input]
 _io._Buffered.read1
-    size as n: Py_ssize_t
+    size as n: Py_ssize_t = -1
     /
 [clinic start generated code]*/
 
 static PyObject *
 _io__Buffered_read1_impl(buffered *self, Py_ssize_t n)
-/*[clinic end generated code: output=bcc4fb4e54d103a3 input=8d2869c18b983184]*/
+/*[clinic end generated code: output=bcc4fb4e54d103a3 input=7d22de9630b61774]*/
 {
     Py_ssize_t have, r;
     PyObject *res = NULL;
 
     CHECK_INITIALIZED(self)
     if (n < 0) {
-        PyErr_SetString(PyExc_ValueError,
-                        "read length must be positive");
-        return NULL;
+        n = self->buffer_size;
     }
 
     CHECK_CLOSED(self, "read of closed file")
diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c
index a1ba121..96be0f4 100644
--- a/Modules/_io/bytesio.c
+++ b/Modules/_io/bytesio.c
@@ -420,7 +420,7 @@
 
 /*[clinic input]
 _io.BytesIO.read1
-    size: object
+    size: object(c_default="Py_None") = -1
     /
 
 Read at most size bytes, returned as a bytes object.
@@ -430,8 +430,8 @@
 [clinic start generated code]*/
 
 static PyObject *
-_io_BytesIO_read1(bytesio *self, PyObject *size)
-/*[clinic end generated code: output=16021f5d0ac3d4e2 input=d4f40bb8f2f99418]*/
+_io_BytesIO_read1_impl(bytesio *self, PyObject *size)
+/*[clinic end generated code: output=a60d80c84c81a6b8 input=0951874bafee8e80]*/
 {
     return _io_BytesIO_read_impl(self, size);
 }
diff --git a/Modules/_io/clinic/bufferedio.c.h b/Modules/_io/clinic/bufferedio.c.h
index 58144a4..dc69c48 100644
--- a/Modules/_io/clinic/bufferedio.c.h
+++ b/Modules/_io/clinic/bufferedio.c.h
@@ -140,23 +140,24 @@
 }
 
 PyDoc_STRVAR(_io__Buffered_read1__doc__,
-"read1($self, size, /)\n"
+"read1($self, size=-1, /)\n"
 "--\n"
 "\n");
 
 #define _IO__BUFFERED_READ1_METHODDEF    \
-    {"read1", (PyCFunction)_io__Buffered_read1, METH_O, _io__Buffered_read1__doc__},
+    {"read1", (PyCFunction)_io__Buffered_read1, METH_VARARGS, _io__Buffered_read1__doc__},
 
 static PyObject *
 _io__Buffered_read1_impl(buffered *self, Py_ssize_t n);
 
 static PyObject *
-_io__Buffered_read1(buffered *self, PyObject *arg)
+_io__Buffered_read1(buffered *self, PyObject *args)
 {
     PyObject *return_value = NULL;
-    Py_ssize_t n;
+    Py_ssize_t n = -1;
 
-    if (!PyArg_Parse(arg, "n:read1", &n)) {
+    if (!PyArg_ParseTuple(args, "|n:read1",
+        &n)) {
         goto exit;
     }
     return_value = _io__Buffered_read1_impl(self, n);
@@ -475,4 +476,4 @@
 exit:
     return return_value;
 }
-/*[clinic end generated code: output=a956f394ecde4cf9 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=490c97bfcfd92c51 input=a9049054013a1b77]*/
diff --git a/Modules/_io/clinic/bytesio.c.h b/Modules/_io/clinic/bytesio.c.h
index c64ce5c..1434782 100644
--- a/Modules/_io/clinic/bytesio.c.h
+++ b/Modules/_io/clinic/bytesio.c.h
@@ -181,7 +181,7 @@
 }
 
 PyDoc_STRVAR(_io_BytesIO_read1__doc__,
-"read1($self, size, /)\n"
+"read1($self, size=-1, /)\n"
 "--\n"
 "\n"
 "Read at most size bytes, returned as a bytes object.\n"
@@ -190,7 +190,27 @@
 "Return an empty bytes object at EOF.");
 
 #define _IO_BYTESIO_READ1_METHODDEF    \
-    {"read1", (PyCFunction)_io_BytesIO_read1, METH_O, _io_BytesIO_read1__doc__},
+    {"read1", (PyCFunction)_io_BytesIO_read1, METH_VARARGS, _io_BytesIO_read1__doc__},
+
+static PyObject *
+_io_BytesIO_read1_impl(bytesio *self, PyObject *size);
+
+static PyObject *
+_io_BytesIO_read1(bytesio *self, PyObject *args)
+{
+    PyObject *return_value = NULL;
+    PyObject *size = Py_None;
+
+    if (!PyArg_UnpackTuple(args, "read1",
+        0, 1,
+        &size)) {
+        goto exit;
+    }
+    return_value = _io_BytesIO_read1_impl(self, size);
+
+exit:
+    return return_value;
+}
 
 PyDoc_STRVAR(_io_BytesIO_readline__doc__,
 "readline($self, size=None, /)\n"
@@ -428,4 +448,4 @@
 exit:
     return return_value;
 }
-/*[clinic end generated code: output=6382e8eb578eea64 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=8f469431da1b3857 input=a9049054013a1b77]*/