From b833b832f8e236eefe5632f338667eff4809c6cf Mon Sep 17 00:00:00 2001 From: Marcel Martin Date: Sat, 22 Jan 2022 22:21:41 +0100 Subject: [PATCH 01/30] Implement BytesIO.peek() --- Lib/_pyio.py | 8 +++++++ Lib/test/test_io/test_memoryio.py | 17 ++++++++++++++ Modules/_io/bytesio.c | 37 ++++++++++++++++++++++++++++++ Modules/_io/clinic/bytesio.c.h | 38 ++++++++++++++++++++++++++++++- 4 files changed, 99 insertions(+), 1 deletion(-) diff --git a/Lib/_pyio.py b/Lib/_pyio.py index 3306c8a274760b..0fac2aa230cc1d 100644 --- a/Lib/_pyio.py +++ b/Lib/_pyio.py @@ -996,6 +996,14 @@ def tell(self): raise ValueError("tell on closed file") return self._pos + def peek(self, size=-1): + pos = self.tell() + if size == 0: + size = -1 + b = self.read(size) + self.seek(pos) + return b + def truncate(self, pos=None): if self.closed: raise ValueError("truncate on closed file") diff --git a/Lib/test/test_io/test_memoryio.py b/Lib/test/test_io/test_memoryio.py index 482b183da23ffa..ca5b9880ee58d4 100644 --- a/Lib/test/test_io/test_memoryio.py +++ b/Lib/test/test_io/test_memoryio.py @@ -566,6 +566,23 @@ def test_issue141311(self): buf = bytearray(2) self.assertEqual(0, memio.readinto(buf)) + def test_peek(self): + buf = self.buftype("1234567890") + memio = self.ioclass(buf) + + self.assertEqual(memio.peek(1), buf[:1]) + self.assertEqual(memio.peek(1), buf[:1]) + self.assertEqual(memio.peek(), buf) + self.assertEqual(memio.peek(0), buf) + memio.read(1) + self.assertEqual(memio.peek(1), buf[1:2]) + self.assertEqual(memio.peek(), buf[1:]) + self.assertEqual(memio.peek(42), buf[1:]) + memio.read() + self.assertEqual(memio.peek(1), self.EOF) + memio.close() + self.assertRaises(ValueError, memio.peek) + def test_unicode(self): memio = self.ioclass() diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c index d088bb0efac797..8761766dc54fbb 100644 --- a/Modules/_io/bytesio.c +++ b/Modules/_io/bytesio.c @@ -499,6 +499,42 @@ _io_BytesIO_read1_impl(bytesio *self, Py_ssize_t size) return _io_BytesIO_read_impl(self, size); } + +/*[clinic input] +_io.BytesIO.peek + size: Py_ssize_t(accept={int, NoneType}) = -1 + / + +Return bytes from the stream without advancing the position. + +Return an empty bytes object at EOF. +[clinic start generated code]*/ + +static PyObject * +_io_BytesIO_peek_impl(bytesio *self, Py_ssize_t size) +/*[clinic end generated code: output=fa4d8ce28b35db9b input=afc80e71b37e7c59]*/ +{ + Py_ssize_t n; + const char *output; + + CHECK_CLOSED(self); + + /* adjust invalid sizes */ + n = self->string_size - self->pos; + if (size < 1 || size > n) { + size = n; + if (size < 0) + size = 0; + } + + assert(self->buf != NULL); + assert(size <= self->string_size); + output = PyBytes_AS_STRING(self->buf) + self->pos; + return PyBytes_FromStringAndSize(output, size); +} + + + /*[clinic input] @critical_section _io.BytesIO.readline @@ -1135,6 +1171,7 @@ static struct PyMethodDef bytesio_methods[] = { _IO_BYTESIO_READLINE_METHODDEF _IO_BYTESIO_READLINES_METHODDEF _IO_BYTESIO_READ_METHODDEF + _IO_BYTESIO_PEEK_METHODDEF _IO_BYTESIO_GETBUFFER_METHODDEF _IO_BYTESIO_GETVALUE_METHODDEF _IO_BYTESIO_SEEK_METHODDEF diff --git a/Modules/_io/clinic/bytesio.c.h b/Modules/_io/clinic/bytesio.c.h index 6595dc937bbcf0..d767bf6f02b3e9 100644 --- a/Modules/_io/clinic/bytesio.c.h +++ b/Modules/_io/clinic/bytesio.c.h @@ -287,6 +287,42 @@ _io_BytesIO_read1(PyObject *self, PyObject *const *args, Py_ssize_t nargs) return return_value; } +PyDoc_STRVAR(_io_BytesIO_peek__doc__, +"peek($self, size=-1, /)\n" +"--\n" +"\n" +"Return bytes from the stream without advancing the position.\n" +"\n" +"Return an empty bytes object at EOF."); + +#define _IO_BYTESIO_PEEK_METHODDEF \ + {"peek", _PyCFunction_CAST(_io_BytesIO_peek), METH_FASTCALL, _io_BytesIO_peek__doc__}, + +static PyObject * +_io_BytesIO_peek_impl(bytesio *self, Py_ssize_t size); + +static PyObject * +_io_BytesIO_peek(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t size = -1; + + if (!_PyArg_CheckPositional("peek", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (!_Py_convert_optional_to_ssize_t(args[0], &size)) { + goto exit; + } +skip_optional: + return_value = _io_BytesIO_peek_impl((bytesio *)self, size); + +exit: + return return_value; +} + PyDoc_STRVAR(_io_BytesIO_readline__doc__, "readline($self, size=-1, /)\n" "--\n" @@ -637,4 +673,4 @@ _io_BytesIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=daa81dfdae5ccc57 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=c21a2170e9f7efa5 input=a9049054013a1b77]*/ From 50a2cfbe60ee646c31ce2947a27ed4fe64286bde Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Sun, 10 Apr 2022 20:11:00 +0000 Subject: [PATCH 02/30] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20b?= =?UTF-8?q?lurb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../NEWS.d/next/Library/2022-04-10-20-10-59.bpo-46375.8j1ogZ.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2022-04-10-20-10-59.bpo-46375.8j1ogZ.rst diff --git a/Misc/NEWS.d/next/Library/2022-04-10-20-10-59.bpo-46375.8j1ogZ.rst b/Misc/NEWS.d/next/Library/2022-04-10-20-10-59.bpo-46375.8j1ogZ.rst new file mode 100644 index 00000000000000..530381efef8746 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-04-10-20-10-59.bpo-46375.8j1ogZ.rst @@ -0,0 +1 @@ +Add a ``peek()`` method to :class:`io.BytesIO`. From eaa76723a2f8801489bc1f2bc1afce447bf51243 Mon Sep 17 00:00:00 2001 From: Marcel Martin Date: Wed, 9 Nov 2022 22:13:41 +0100 Subject: [PATCH 03/30] Document BytesIO.peek() --- Doc/library/io.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Doc/library/io.rst b/Doc/library/io.rst index 494e57fe1c0474..6114495a66d457 100644 --- a/Doc/library/io.rst +++ b/Doc/library/io.rst @@ -739,6 +739,12 @@ than raw I/O does. Return :class:`bytes` containing the entire contents of the buffer. + .. method:: peek(size=0, /) + + .. versionadded:: 3.12 + + Return bytes from the current position onwards but without advancing the + position. The number of bytes returned may be less or more than requested. .. method:: read1(size=-1, /) From 00457ae459ba4174f2038bb7fdf6d7b12379f97f Mon Sep 17 00:00:00 2001 From: Marcel Martin Date: Wed, 9 Nov 2022 22:18:46 +0100 Subject: [PATCH 04/30] Implement with the help of read_bytes() This allows peek() to use the same optimization that read_bytes() has of returning a reference to the buffer when possible (without copying). --- Modules/_io/bytesio.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c index 8761766dc54fbb..a97ada39451ceb 100644 --- a/Modules/_io/bytesio.c +++ b/Modules/_io/bytesio.c @@ -526,11 +526,11 @@ _io_BytesIO_peek_impl(bytesio *self, Py_ssize_t size) if (size < 0) size = 0; } + Py_ssize_t prev_pos = self->pos; + PyObject* result = read_bytes_lock_held(self, size); + self->pos = prev_pos; - assert(self->buf != NULL); - assert(size <= self->string_size); - output = PyBytes_AS_STRING(self->buf) + self->pos; - return PyBytes_FromStringAndSize(output, size); + return result; } From 882579d16d6bd70396bdbc61fab2ed3bb907f3ab Mon Sep 17 00:00:00 2001 From: Marcel Martin Date: Sat, 8 Jul 2023 14:29:35 +0200 Subject: [PATCH 05/30] =?UTF-8?q?Add=20to=20What=E2=80=99s=20New?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Doc/whatsnew/3.15.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index 927d6035c8c4bc..ae07ac094cf586 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -840,6 +840,14 @@ inspect for :func:`~inspect.getdoc`. (Contributed by Serhiy Storchaka in :gh:`132686`.) + +io +-- + +* Add :meth:`~io.BytesIO.peek`. + (Contributed by Marcel Martin in :gh:`90533`.) + + json ---- From c1eed72ef5ebbe6e157e78491fc778f1681193fe Mon Sep 17 00:00:00 2001 From: Marcel Martin Date: Sat, 8 Jul 2023 14:33:54 +0200 Subject: [PATCH 06/30] versionadded: 3.12 -> 3.13 --- Doc/library/io.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/io.rst b/Doc/library/io.rst index 6114495a66d457..5abc6e86f2e438 100644 --- a/Doc/library/io.rst +++ b/Doc/library/io.rst @@ -741,7 +741,7 @@ than raw I/O does. .. method:: peek(size=0, /) - .. versionadded:: 3.12 + .. versionadded:: 3.13 Return bytes from the current position onwards but without advancing the position. The number of bytes returned may be less or more than requested. From afc200cbd589e3fa1c85e30faaa893e1f34982de Mon Sep 17 00:00:00 2001 From: Marcel Martin Date: Sat, 8 Jul 2023 14:35:22 +0200 Subject: [PATCH 07/30] Remove unused variable --- Modules/_io/bytesio.c | 1 - 1 file changed, 1 deletion(-) diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c index a97ada39451ceb..f7b31d05aff701 100644 --- a/Modules/_io/bytesio.c +++ b/Modules/_io/bytesio.c @@ -515,7 +515,6 @@ _io_BytesIO_peek_impl(bytesio *self, Py_ssize_t size) /*[clinic end generated code: output=fa4d8ce28b35db9b input=afc80e71b37e7c59]*/ { Py_ssize_t n; - const char *output; CHECK_CLOSED(self); From 79ab9a4886db9bd4e5d6306087b5c84e1b1872b1 Mon Sep 17 00:00:00 2001 From: Marcel Martin Date: Fri, 22 Sep 2023 09:49:24 +0200 Subject: [PATCH 08/30] Test tell() after peek() --- Lib/test/test_io/test_memoryio.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_io/test_memoryio.py b/Lib/test/test_io/test_memoryio.py index ca5b9880ee58d4..3de42297a9a13e 100644 --- a/Lib/test/test_io/test_memoryio.py +++ b/Lib/test/test_io/test_memoryio.py @@ -569,11 +569,12 @@ def test_issue141311(self): def test_peek(self): buf = self.buftype("1234567890") memio = self.ioclass(buf) - + pos = memio.tell() self.assertEqual(memio.peek(1), buf[:1]) self.assertEqual(memio.peek(1), buf[:1]) self.assertEqual(memio.peek(), buf) self.assertEqual(memio.peek(0), buf) + self.assertEqual(memio.tell(), pos) memio.read(1) self.assertEqual(memio.peek(1), buf[1:2]) self.assertEqual(memio.peek(), buf[1:]) From b4939148aeb51c2c7b4cd42cf3a64d9905224b57 Mon Sep 17 00:00:00 2001 From: Marcel Martin Date: Fri, 22 Sep 2023 09:49:55 +0200 Subject: [PATCH 09/30] Update docs, factor out peek_bytes, semantics Semantic change: The default argument for peek is now size=1. --- Doc/library/io.rst | 11 +++++++---- Lib/_pyio.py | 13 ++++++------- Lib/test/test_io/test_memoryio.py | 5 +++-- Modules/_io/bytesio.c | 23 +++++++++++++---------- Modules/_io/clinic/bytesio.c.h | 20 +++++++++++++++----- 5 files changed, 44 insertions(+), 28 deletions(-) diff --git a/Doc/library/io.rst b/Doc/library/io.rst index 5abc6e86f2e438..837cfdc7acfa9a 100644 --- a/Doc/library/io.rst +++ b/Doc/library/io.rst @@ -739,12 +739,15 @@ than raw I/O does. Return :class:`bytes` containing the entire contents of the buffer. - .. method:: peek(size=0, /) - - .. versionadded:: 3.13 + .. method:: peek(size=1, /) Return bytes from the current position onwards but without advancing the - position. The number of bytes returned may be less or more than requested. + position. If the size argument is less than one or larger than the number + of available bytes, a copy of the buffer from the current position until + the end is returned. + Return an empty bytes object at EOF. + + .. versionadded:: 3.15 .. method:: read1(size=-1, /) diff --git a/Lib/_pyio.py b/Lib/_pyio.py index 0fac2aa230cc1d..1b38614420061d 100644 --- a/Lib/_pyio.py +++ b/Lib/_pyio.py @@ -996,13 +996,12 @@ def tell(self): raise ValueError("tell on closed file") return self._pos - def peek(self, size=-1): - pos = self.tell() - if size == 0: - size = -1 - b = self.read(size) - self.seek(pos) - return b + def peek(self, size=1): + if self.closed: + raise ValueError("peek on closed file") + if size < 1: + size = len(self._buffer) - self._pos + return self._buffer[self._pos : self._pos + size] def truncate(self, pos=None): if self.closed: diff --git a/Lib/test/test_io/test_memoryio.py b/Lib/test/test_io/test_memoryio.py index 3de42297a9a13e..4d6d731bd7c36b 100644 --- a/Lib/test/test_io/test_memoryio.py +++ b/Lib/test/test_io/test_memoryio.py @@ -572,12 +572,13 @@ def test_peek(self): pos = memio.tell() self.assertEqual(memio.peek(1), buf[:1]) self.assertEqual(memio.peek(1), buf[:1]) - self.assertEqual(memio.peek(), buf) + self.assertEqual(memio.peek(), buf[:1]) self.assertEqual(memio.peek(0), buf) self.assertEqual(memio.tell(), pos) memio.read(1) self.assertEqual(memio.peek(1), buf[1:2]) - self.assertEqual(memio.peek(), buf[1:]) + self.assertEqual(memio.peek(), buf[1:2]) + self.assertEqual(memio.peek(0), buf[1:]) self.assertEqual(memio.peek(42), buf[1:]) memio.read() self.assertEqual(memio.peek(1), self.EOF) diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c index f7b31d05aff701..fe0ee7e416fe95 100644 --- a/Modules/_io/bytesio.c +++ b/Modules/_io/bytesio.c @@ -420,8 +420,9 @@ _io_BytesIO_tell_impl(bytesio *self) return PyLong_FromSsize_t(self->pos); } +// Read without advancing position static PyObject * -read_bytes_lock_held(bytesio *self, Py_ssize_t size) +peek_bytes_lock_held(bytesio *self, Py_ssize_t size) { _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(self); @@ -432,7 +433,6 @@ read_bytes_lock_held(bytesio *self, Py_ssize_t size) if (size > 1 && self->pos == 0 && size == PyBytes_GET_SIZE(self->buf) && FT_ATOMIC_LOAD_SSIZE_RELAXED(self->exports) == 0) { - self->pos += size; return Py_NewRef(self->buf); } @@ -444,10 +444,16 @@ read_bytes_lock_held(bytesio *self, Py_ssize_t size) } output = PyBytes_AS_STRING(self->buf) + self->pos; - self->pos += size; return PyBytes_FromStringAndSize(output, size); } +static PyObject * +read_bytes_lock_held(bytesio *self, Py_ssize_t size) { + PyObject *bytes = peek_bytes_lock_held(self, size); + self->pos += size; + return bytes; +} + /*[clinic input] @critical_section _io.BytesIO.read @@ -502,17 +508,18 @@ _io_BytesIO_read1_impl(bytesio *self, Py_ssize_t size) /*[clinic input] _io.BytesIO.peek - size: Py_ssize_t(accept={int, NoneType}) = -1 + size: Py_ssize_t = 1 / Return bytes from the stream without advancing the position. +If the size argument is zero or negative, read until EOF is reached. Return an empty bytes object at EOF. [clinic start generated code]*/ static PyObject * _io_BytesIO_peek_impl(bytesio *self, Py_ssize_t size) -/*[clinic end generated code: output=fa4d8ce28b35db9b input=afc80e71b37e7c59]*/ +/*[clinic end generated code: output=fa4d8ce28b35db9b input=cb06614a3ed0496e]*/ { Py_ssize_t n; @@ -525,11 +532,7 @@ _io_BytesIO_peek_impl(bytesio *self, Py_ssize_t size) if (size < 0) size = 0; } - Py_ssize_t prev_pos = self->pos; - PyObject* result = read_bytes_lock_held(self, size); - self->pos = prev_pos; - - return result; + return peek_bytes_lock_held(self, size); } diff --git a/Modules/_io/clinic/bytesio.c.h b/Modules/_io/clinic/bytesio.c.h index d767bf6f02b3e9..fe3ec2f3bcad0b 100644 --- a/Modules/_io/clinic/bytesio.c.h +++ b/Modules/_io/clinic/bytesio.c.h @@ -288,11 +288,12 @@ _io_BytesIO_read1(PyObject *self, PyObject *const *args, Py_ssize_t nargs) } PyDoc_STRVAR(_io_BytesIO_peek__doc__, -"peek($self, size=-1, /)\n" +"peek($self, size=1, /)\n" "--\n" "\n" "Return bytes from the stream without advancing the position.\n" "\n" +"If the size argument is zero or negative, read until EOF is reached.\n" "Return an empty bytes object at EOF."); #define _IO_BYTESIO_PEEK_METHODDEF \ @@ -305,7 +306,7 @@ static PyObject * _io_BytesIO_peek(PyObject *self, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - Py_ssize_t size = -1; + Py_ssize_t size = 1; if (!_PyArg_CheckPositional("peek", nargs, 0, 1)) { goto exit; @@ -313,8 +314,17 @@ _io_BytesIO_peek(PyObject *self, PyObject *const *args, Py_ssize_t nargs) if (nargs < 1) { goto skip_optional; } - if (!_Py_convert_optional_to_ssize_t(args[0], &size)) { - goto exit; + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[0]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + size = ival; } skip_optional: return_value = _io_BytesIO_peek_impl((bytesio *)self, size); @@ -673,4 +683,4 @@ _io_BytesIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=c21a2170e9f7efa5 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=02299ed558ba722f input=a9049054013a1b77]*/ From 2a1c85c513f6c83ff3b48181239be2e679738908 Mon Sep 17 00:00:00 2001 From: Marcel Martin Date: Fri, 29 Sep 2023 00:49:27 +0200 Subject: [PATCH 10/30] Update Misc/NEWS.d/next/Library/2022-04-10-20-10-59.bpo-46375.8j1ogZ.rst Co-authored-by: Erlend E. Aasland --- .../next/Library/2022-04-10-20-10-59.bpo-46375.8j1ogZ.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2022-04-10-20-10-59.bpo-46375.8j1ogZ.rst b/Misc/NEWS.d/next/Library/2022-04-10-20-10-59.bpo-46375.8j1ogZ.rst index 530381efef8746..c11f101b749c17 100644 --- a/Misc/NEWS.d/next/Library/2022-04-10-20-10-59.bpo-46375.8j1ogZ.rst +++ b/Misc/NEWS.d/next/Library/2022-04-10-20-10-59.bpo-46375.8j1ogZ.rst @@ -1 +1 @@ -Add a ``peek()`` method to :class:`io.BytesIO`. +Add :meth:`io.BytesIO.peek`. From d398717b1b6907376ef42e4a8ac8060af8e13ed1 Mon Sep 17 00:00:00 2001 From: Marcel Martin Date: Fri, 29 Sep 2023 00:50:46 +0200 Subject: [PATCH 11/30] Update Modules/_io/bytesio.c Co-authored-by: Erlend E. Aasland --- Modules/_io/bytesio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c index fe0ee7e416fe95..4106806bef8047 100644 --- a/Modules/_io/bytesio.c +++ b/Modules/_io/bytesio.c @@ -448,7 +448,8 @@ peek_bytes_lock_held(bytesio *self, Py_ssize_t size) } static PyObject * -read_bytes_lock_held(bytesio *self, Py_ssize_t size) { +read_bytes_lock_held(bytesio *self, Py_ssize_t size) +{ PyObject *bytes = peek_bytes_lock_held(self, size); self->pos += size; return bytes; From 26d1e81ed12601132b2fc8500b372dc357fa8ae2 Mon Sep 17 00:00:00 2001 From: Marcel Martin Date: Fri, 29 Sep 2023 00:51:19 +0200 Subject: [PATCH 12/30] Update Modules/_io/bytesio.c Co-authored-by: Erlend E. Aasland --- Modules/_io/bytesio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c index 4106806bef8047..e610acf107770f 100644 --- a/Modules/_io/bytesio.c +++ b/Modules/_io/bytesio.c @@ -530,8 +530,9 @@ _io_BytesIO_peek_impl(bytesio *self, Py_ssize_t size) n = self->string_size - self->pos; if (size < 1 || size > n) { size = n; - if (size < 0) + if (size < 0) { size = 0; + } } return peek_bytes_lock_held(self, size); } From 9a19ff95ef56b2cdba4165cf451b97e1539f7bc7 Mon Sep 17 00:00:00 2001 From: Marcel Martin Date: Fri, 29 Sep 2023 00:25:06 +0200 Subject: [PATCH 13/30] Use SemBr Co-authored-by: Erlend E. Aasland --- Doc/library/io.rst | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Doc/library/io.rst b/Doc/library/io.rst index 837cfdc7acfa9a..a6b25b52b59770 100644 --- a/Doc/library/io.rst +++ b/Doc/library/io.rst @@ -741,10 +741,9 @@ than raw I/O does. .. method:: peek(size=1, /) - Return bytes from the current position onwards but without advancing the - position. If the size argument is less than one or larger than the number - of available bytes, a copy of the buffer from the current position until - the end is returned. + Return bytes from the current position onwards without advancing the position. + If the size argument is less than one or larger than the number of available bytes, + a copy of the buffer from the current position until the end is returned. Return an empty bytes object at EOF. .. versionadded:: 3.15 From 9300ade195c04f02b62aaf03f315ccecb3781532 Mon Sep 17 00:00:00 2001 From: Marcel Martin Date: Fri, 29 Sep 2023 00:54:10 +0200 Subject: [PATCH 14/30] Update Doc/whatsnew/3.13.rst Co-authored-by: Erlend E. Aasland --- Doc/whatsnew/3.15.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index ae07ac094cf586..0bb823b5062a80 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -844,7 +844,7 @@ inspect io -- -* Add :meth:`~io.BytesIO.peek`. +* Add :meth:`io.BytesIO.peek`. (Contributed by Marcel Martin in :gh:`90533`.) From d214089c1da33dd33a1b5d75362d54ff6bcc24a6 Mon Sep 17 00:00:00 2001 From: Marcel Martin Date: Fri, 29 Sep 2023 00:55:39 +0200 Subject: [PATCH 15/30] Apply suggestions from code review Co-authored-by: Victor Stinner --- Lib/test/test_io/test_memoryio.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_io/test_memoryio.py b/Lib/test/test_io/test_memoryio.py index 4d6d731bd7c36b..f50e7e1246f4e2 100644 --- a/Lib/test/test_io/test_memoryio.py +++ b/Lib/test/test_io/test_memoryio.py @@ -569,12 +569,12 @@ def test_issue141311(self): def test_peek(self): buf = self.buftype("1234567890") memio = self.ioclass(buf) - pos = memio.tell() + self.assertEqual(memio.tell(), 0) self.assertEqual(memio.peek(1), buf[:1]) self.assertEqual(memio.peek(1), buf[:1]) self.assertEqual(memio.peek(), buf[:1]) self.assertEqual(memio.peek(0), buf) - self.assertEqual(memio.tell(), pos) + self.assertEqual(memio.tell(), 0) memio.read(1) self.assertEqual(memio.peek(1), buf[1:2]) self.assertEqual(memio.peek(), buf[1:2]) From d6691b81b2f49504b16b26bab4a4af76d7ac1ade Mon Sep 17 00:00:00 2001 From: Marcel Martin Date: Fri, 29 Sep 2023 00:58:42 +0200 Subject: [PATCH 16/30] Use a context manager around memio in test_peek --- Lib/test/test_io/test_memoryio.py | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/Lib/test/test_io/test_memoryio.py b/Lib/test/test_io/test_memoryio.py index f50e7e1246f4e2..bd52237d841aff 100644 --- a/Lib/test/test_io/test_memoryio.py +++ b/Lib/test/test_io/test_memoryio.py @@ -568,21 +568,20 @@ def test_issue141311(self): def test_peek(self): buf = self.buftype("1234567890") - memio = self.ioclass(buf) - self.assertEqual(memio.tell(), 0) - self.assertEqual(memio.peek(1), buf[:1]) - self.assertEqual(memio.peek(1), buf[:1]) - self.assertEqual(memio.peek(), buf[:1]) - self.assertEqual(memio.peek(0), buf) - self.assertEqual(memio.tell(), 0) - memio.read(1) - self.assertEqual(memio.peek(1), buf[1:2]) - self.assertEqual(memio.peek(), buf[1:2]) - self.assertEqual(memio.peek(0), buf[1:]) - self.assertEqual(memio.peek(42), buf[1:]) - memio.read() - self.assertEqual(memio.peek(1), self.EOF) - memio.close() + with self.ioclass(buf) as memio: + self.assertEqual(memio.tell(), 0) + self.assertEqual(memio.peek(1), buf[:1]) + self.assertEqual(memio.peek(1), buf[:1]) + self.assertEqual(memio.peek(), buf[:1]) + self.assertEqual(memio.peek(0), buf) + self.assertEqual(memio.tell(), 0) + memio.read(1) + self.assertEqual(memio.peek(1), buf[1:2]) + self.assertEqual(memio.peek(), buf[1:2]) + self.assertEqual(memio.peek(0), buf[1:]) + self.assertEqual(memio.peek(42), buf[1:]) + memio.read() + self.assertEqual(memio.peek(1), self.EOF) self.assertRaises(ValueError, memio.peek) def test_unicode(self): From 3e51adbb4a9b20d24665d6988e3e83887fb554f5 Mon Sep 17 00:00:00 2001 From: Marcel Martin Date: Fri, 29 Sep 2023 01:01:41 +0200 Subject: [PATCH 17/30] Add more tests for tell() after peek() --- Lib/test/test_io/test_memoryio.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Lib/test/test_io/test_memoryio.py b/Lib/test/test_io/test_memoryio.py index bd52237d841aff..8fc4751525ef35 100644 --- a/Lib/test/test_io/test_memoryio.py +++ b/Lib/test/test_io/test_memoryio.py @@ -576,12 +576,16 @@ def test_peek(self): self.assertEqual(memio.peek(0), buf) self.assertEqual(memio.tell(), 0) memio.read(1) + self.assertEqual(memio.tell(), 1) self.assertEqual(memio.peek(1), buf[1:2]) self.assertEqual(memio.peek(), buf[1:2]) self.assertEqual(memio.peek(0), buf[1:]) self.assertEqual(memio.peek(42), buf[1:]) + self.assertEqual(memio.tell(), 1) memio.read() + self.assertEqual(memio.tell(), len(buf)) self.assertEqual(memio.peek(1), self.EOF) + self.assertEqual(memio.tell(), len(buf)) self.assertRaises(ValueError, memio.peek) def test_unicode(self): From 3661b65866114bbbe3b23a253d6ef95123d6bb88 Mon Sep 17 00:00:00 2001 From: Marcel Martin Date: Fri, 29 Sep 2023 01:05:17 +0200 Subject: [PATCH 18/30] Document why size < 0 can happen --- Modules/_io/bytesio.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c index e610acf107770f..ea24a86ed359eb 100644 --- a/Modules/_io/bytesio.c +++ b/Modules/_io/bytesio.c @@ -530,6 +530,7 @@ _io_BytesIO_peek_impl(bytesio *self, Py_ssize_t size) n = self->string_size - self->pos; if (size < 1 || size > n) { size = n; + /* size can be negative after truncate() */ if (size < 0) { size = 0; } From cd40d77ba90c67ad8c3f32b6c327dcb1d268df4b Mon Sep 17 00:00:00 2001 From: Marcel Martin Date: Fri, 29 Sep 2023 09:18:17 +0200 Subject: [PATCH 19/30] Update Modules/_io/bytesio.c Co-authored-by: Erlend E. Aasland --- Modules/_io/bytesio.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c index ea24a86ed359eb..c94ab03a76e186 100644 --- a/Modules/_io/bytesio.c +++ b/Modules/_io/bytesio.c @@ -522,12 +522,10 @@ static PyObject * _io_BytesIO_peek_impl(bytesio *self, Py_ssize_t size) /*[clinic end generated code: output=fa4d8ce28b35db9b input=cb06614a3ed0496e]*/ { - Py_ssize_t n; - CHECK_CLOSED(self); /* adjust invalid sizes */ - n = self->string_size - self->pos; + Py_ssize_t n = self->string_size - self->pos; if (size < 1 || size > n) { size = n; /* size can be negative after truncate() */ From 04372bd9f79f9e80eb1fca88c5c112dd0b13240f Mon Sep 17 00:00:00 2001 From: Marcel Martin Date: Fri, 29 Sep 2023 09:17:09 +0200 Subject: [PATCH 20/30] Do not update pos if peek_bytes failed --- Modules/_io/bytesio.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c index c94ab03a76e186..03d0594920b907 100644 --- a/Modules/_io/bytesio.c +++ b/Modules/_io/bytesio.c @@ -451,7 +451,9 @@ static PyObject * read_bytes_lock_held(bytesio *self, Py_ssize_t size) { PyObject *bytes = peek_bytes_lock_held(self, size); - self->pos += size; + if (bytes != NULL) { + self->pos += size; + } return bytes; } From 6b9ae8c47c800b135618a6ae4811497b96bcae75 Mon Sep 17 00:00:00 2001 From: Marcel Martin Date: Fri, 29 Sep 2023 09:17:42 +0200 Subject: [PATCH 21/30] Size can be negative after truncate or seek --- Modules/_io/bytesio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c index 03d0594920b907..e4da995b7ff485 100644 --- a/Modules/_io/bytesio.c +++ b/Modules/_io/bytesio.c @@ -530,7 +530,7 @@ _io_BytesIO_peek_impl(bytesio *self, Py_ssize_t size) Py_ssize_t n = self->string_size - self->pos; if (size < 1 || size > n) { size = n; - /* size can be negative after truncate() */ + /* size can be negative after truncate() or seek() */ if (size < 0) { size = 0; } From f7406f676cbdf3f9f9c628fa5a4770745289663f Mon Sep 17 00:00:00 2001 From: Marcel Martin Date: Fri, 29 Sep 2023 10:39:34 +0200 Subject: [PATCH 22/30] Test with size<0 and size>len(buf) --- Lib/test/test_io/test_memoryio.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_io/test_memoryio.py b/Lib/test/test_io/test_memoryio.py index 8fc4751525ef35..4d07ed0cc87c48 100644 --- a/Lib/test/test_io/test_memoryio.py +++ b/Lib/test/test_io/test_memoryio.py @@ -574,13 +574,16 @@ def test_peek(self): self.assertEqual(memio.peek(1), buf[:1]) self.assertEqual(memio.peek(), buf[:1]) self.assertEqual(memio.peek(0), buf) + self.assertEqual(memio.peek(len(buf) + 100), buf) + self.assertEqual(memio.peek(-1), buf) self.assertEqual(memio.tell(), 0) memio.read(1) self.assertEqual(memio.tell(), 1) self.assertEqual(memio.peek(1), buf[1:2]) self.assertEqual(memio.peek(), buf[1:2]) self.assertEqual(memio.peek(0), buf[1:]) - self.assertEqual(memio.peek(42), buf[1:]) + self.assertEqual(memio.peek(len(buf) + 100), buf[1:]) + self.assertEqual(memio.peek(-1), buf[1:]) self.assertEqual(memio.tell(), 1) memio.read() self.assertEqual(memio.tell(), len(buf)) From d9528e24987baad7f2f9cc7a29b90b0fee9de72b Mon Sep 17 00:00:00 2001 From: Marcel Martin Date: Fri, 29 Sep 2023 11:48:57 +0200 Subject: [PATCH 23/30] Test peek() after write() --- Lib/test/test_io/test_memoryio.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Lib/test/test_io/test_memoryio.py b/Lib/test/test_io/test_memoryio.py index 4d07ed0cc87c48..6b471d4b3cef6a 100644 --- a/Lib/test/test_io/test_memoryio.py +++ b/Lib/test/test_io/test_memoryio.py @@ -589,6 +589,16 @@ def test_peek(self): self.assertEqual(memio.tell(), len(buf)) self.assertEqual(memio.peek(1), self.EOF) self.assertEqual(memio.tell(), len(buf)) + # Peeking works after writing + abc = self.buftype("abc") + memio.write(abc) + self.assertEqual(memio.peek(), self.EOF) + memio.seek(len(buf)) + self.assertEqual(memio.peek(), abc[:1]) + self.assertEqual(memio.peek(-1), abc) + self.assertEqual(memio.peek(len(abc) + 100), abc) + self.assertEqual(memio.tell(), len(buf)) + self.assertRaises(ValueError, memio.peek) def test_unicode(self): From bc8134bf8173718995c2ebaefdfc188eb5d61c73 Mon Sep 17 00:00:00 2001 From: Marcel Martin Date: Fri, 29 Sep 2023 15:53:11 +0200 Subject: [PATCH 24/30] Document BufferedReader.peek and BytesIO.peek similarly --- Doc/library/io.rst | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Doc/library/io.rst b/Doc/library/io.rst index a6b25b52b59770..481bc0071294da 100644 --- a/Doc/library/io.rst +++ b/Doc/library/io.rst @@ -742,9 +742,10 @@ than raw I/O does. .. method:: peek(size=1, /) Return bytes from the current position onwards without advancing the position. + At least one byte of data is returned if not at EOF. + Return an empty :class:`bytes` object at EOF. If the size argument is less than one or larger than the number of available bytes, a copy of the buffer from the current position until the end is returned. - Return an empty bytes object at EOF. .. versionadded:: 3.15 @@ -780,8 +781,12 @@ than raw I/O does. .. method:: peek(size=0, /) - Return bytes from the stream without advancing the position. The number of - bytes returned may be less or more than requested. If the underlying raw + Return bytes from the current position onwards without advancing the position. + At least one byte of data is returned if not at EOF. + Return an empty :class:`bytes` object at EOF. + At most one single read on the underlying raw stream is done to satisfy the call. + The exact number of bytes returned is unspecified + (*size* is ignored). If the underlying raw stream is non-blocking and the operation would block, returns empty bytes. .. method:: read(size=-1, /) From b6ffca868b55b0a82e2e65504d41bd74c63689b3 Mon Sep 17 00:00:00 2001 From: Marcel Martin Date: Fri, 29 Sep 2023 16:02:09 +0200 Subject: [PATCH 25/30] Comment --- Lib/_pyio.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Lib/_pyio.py b/Lib/_pyio.py index 1b38614420061d..185b2aac1af025 100644 --- a/Lib/_pyio.py +++ b/Lib/_pyio.py @@ -999,6 +999,9 @@ def tell(self): def peek(self, size=1): if self.closed: raise ValueError("peek on closed file") + # Due to slicing semantics, this works correctly + # even if the size is greater than the buffer length or + # the position is beyond the end of the buffer if size < 1: size = len(self._buffer) - self._pos return self._buffer[self._pos : self._pos + size] From 5fe5645ca38caf43d1aa3bd2ffeae304b6d83a15 Mon Sep 17 00:00:00 2001 From: Marcel Martin Date: Fri, 29 Sep 2023 16:45:54 +0200 Subject: [PATCH 26/30] Make it more explicit that size is ignored --- Doc/library/io.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Doc/library/io.rst b/Doc/library/io.rst index 481bc0071294da..a44ca640d71fd2 100644 --- a/Doc/library/io.rst +++ b/Doc/library/io.rst @@ -785,8 +785,9 @@ than raw I/O does. At least one byte of data is returned if not at EOF. Return an empty :class:`bytes` object at EOF. At most one single read on the underlying raw stream is done to satisfy the call. - The exact number of bytes returned is unspecified - (*size* is ignored). If the underlying raw + The *size* argument is ignored. + The number of read bytes depends on the buffer size and the current position in the internal buffer. + If the underlying raw stream is non-blocking and the operation would block, returns empty bytes. .. method:: read(size=-1, /) From 4126a64eb0add5e5f361184839710797c444e99b Mon Sep 17 00:00:00 2001 From: Marcel Martin Date: Mon, 23 Oct 2023 08:47:15 +0200 Subject: [PATCH 27/30] Return an empty bytes object for size=0 --- Doc/library/io.rst | 2 +- Lib/_pyio.py | 2 +- Lib/test/test_io/test_memoryio.py | 5 +++-- Modules/_io/bytesio.c | 6 +++--- Modules/_io/clinic/bytesio.c.h | 2 +- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/Doc/library/io.rst b/Doc/library/io.rst index a44ca640d71fd2..88180cb9fba844 100644 --- a/Doc/library/io.rst +++ b/Doc/library/io.rst @@ -744,7 +744,7 @@ than raw I/O does. Return bytes from the current position onwards without advancing the position. At least one byte of data is returned if not at EOF. Return an empty :class:`bytes` object at EOF. - If the size argument is less than one or larger than the number of available bytes, + If the size argument is negative or larger than the number of available bytes, a copy of the buffer from the current position until the end is returned. .. versionadded:: 3.15 diff --git a/Lib/_pyio.py b/Lib/_pyio.py index 185b2aac1af025..bbf572b5e578a3 100644 --- a/Lib/_pyio.py +++ b/Lib/_pyio.py @@ -1002,7 +1002,7 @@ def peek(self, size=1): # Due to slicing semantics, this works correctly # even if the size is greater than the buffer length or # the position is beyond the end of the buffer - if size < 1: + if size < 0: size = len(self._buffer) - self._pos return self._buffer[self._pos : self._pos + size] diff --git a/Lib/test/test_io/test_memoryio.py b/Lib/test/test_io/test_memoryio.py index 6b471d4b3cef6a..afcf69f003e6d7 100644 --- a/Lib/test/test_io/test_memoryio.py +++ b/Lib/test/test_io/test_memoryio.py @@ -573,7 +573,7 @@ def test_peek(self): self.assertEqual(memio.peek(1), buf[:1]) self.assertEqual(memio.peek(1), buf[:1]) self.assertEqual(memio.peek(), buf[:1]) - self.assertEqual(memio.peek(0), buf) + self.assertEqual(memio.peek(0), b"") self.assertEqual(memio.peek(len(buf) + 100), buf) self.assertEqual(memio.peek(-1), buf) self.assertEqual(memio.tell(), 0) @@ -581,13 +581,14 @@ def test_peek(self): self.assertEqual(memio.tell(), 1) self.assertEqual(memio.peek(1), buf[1:2]) self.assertEqual(memio.peek(), buf[1:2]) - self.assertEqual(memio.peek(0), buf[1:]) + self.assertEqual(memio.peek(0), b"") self.assertEqual(memio.peek(len(buf) + 100), buf[1:]) self.assertEqual(memio.peek(-1), buf[1:]) self.assertEqual(memio.tell(), 1) memio.read() self.assertEqual(memio.tell(), len(buf)) self.assertEqual(memio.peek(1), self.EOF) + self.assertEqual(memio.peek(0), b"") self.assertEqual(memio.tell(), len(buf)) # Peeking works after writing abc = self.buftype("abc") diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c index e4da995b7ff485..84f0693f4626e7 100644 --- a/Modules/_io/bytesio.c +++ b/Modules/_io/bytesio.c @@ -516,7 +516,7 @@ _io.BytesIO.peek Return bytes from the stream without advancing the position. -If the size argument is zero or negative, read until EOF is reached. +If the size argument is negative, read until EOF is reached. Return an empty bytes object at EOF. [clinic start generated code]*/ @@ -528,9 +528,9 @@ _io_BytesIO_peek_impl(bytesio *self, Py_ssize_t size) /* adjust invalid sizes */ Py_ssize_t n = self->string_size - self->pos; - if (size < 1 || size > n) { + if (size < 0 || size > n) { size = n; - /* size can be negative after truncate() or seek() */ + /* n can be negative after truncate() or seek() */ if (size < 0) { size = 0; } diff --git a/Modules/_io/clinic/bytesio.c.h b/Modules/_io/clinic/bytesio.c.h index fe3ec2f3bcad0b..195eaca5ca14a4 100644 --- a/Modules/_io/clinic/bytesio.c.h +++ b/Modules/_io/clinic/bytesio.c.h @@ -293,7 +293,7 @@ PyDoc_STRVAR(_io_BytesIO_peek__doc__, "\n" "Return bytes from the stream without advancing the position.\n" "\n" -"If the size argument is zero or negative, read until EOF is reached.\n" +"If the size argument is negative, read until EOF is reached.\n" "Return an empty bytes object at EOF."); #define _IO_BYTESIO_PEEK_METHODDEF \ From 1ea40c26f359628f6d33d329b5b8501297bca860 Mon Sep 17 00:00:00 2001 From: Marcel Martin Date: Mon, 23 Oct 2023 09:10:13 +0200 Subject: [PATCH 28/30] Simplify --- Lib/_pyio.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Lib/_pyio.py b/Lib/_pyio.py index bbf572b5e578a3..fc6da3ac701fdc 100644 --- a/Lib/_pyio.py +++ b/Lib/_pyio.py @@ -999,12 +999,9 @@ def tell(self): def peek(self, size=1): if self.closed: raise ValueError("peek on closed file") - # Due to slicing semantics, this works correctly - # even if the size is greater than the buffer length or - # the position is beyond the end of the buffer if size < 0: - size = len(self._buffer) - self._pos - return self._buffer[self._pos : self._pos + size] + return self._buffer[self._pos:] + return self._buffer[self._pos:self._pos + size] def truncate(self, pos=None): if self.closed: From 77e04d6bb53ea12a94797cc62e9b45dcbf4a1be9 Mon Sep 17 00:00:00 2001 From: Marcel Martin Date: Mon, 23 Oct 2023 09:11:33 +0200 Subject: [PATCH 29/30] Test peek(3) and peek(5) --- Lib/test/test_io/test_memoryio.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Lib/test/test_io/test_memoryio.py b/Lib/test/test_io/test_memoryio.py index afcf69f003e6d7..4393ed074fae24 100644 --- a/Lib/test/test_io/test_memoryio.py +++ b/Lib/test/test_io/test_memoryio.py @@ -573,6 +573,8 @@ def test_peek(self): self.assertEqual(memio.peek(1), buf[:1]) self.assertEqual(memio.peek(1), buf[:1]) self.assertEqual(memio.peek(), buf[:1]) + self.assertEqual(memio.peek(3), buf[:3]) + self.assertEqual(memio.peek(5), buf[:5]) self.assertEqual(memio.peek(0), b"") self.assertEqual(memio.peek(len(buf) + 100), buf) self.assertEqual(memio.peek(-1), buf) @@ -581,6 +583,8 @@ def test_peek(self): self.assertEqual(memio.tell(), 1) self.assertEqual(memio.peek(1), buf[1:2]) self.assertEqual(memio.peek(), buf[1:2]) + self.assertEqual(memio.peek(3), buf[1:4]) + self.assertEqual(memio.peek(5), buf[1:6]) self.assertEqual(memio.peek(0), b"") self.assertEqual(memio.peek(len(buf) + 100), buf[1:]) self.assertEqual(memio.peek(-1), buf[1:]) @@ -588,6 +592,8 @@ def test_peek(self): memio.read() self.assertEqual(memio.tell(), len(buf)) self.assertEqual(memio.peek(1), self.EOF) + self.assertEqual(memio.peek(3), self.EOF) + self.assertEqual(memio.peek(5), self.EOF) self.assertEqual(memio.peek(0), b"") self.assertEqual(memio.tell(), len(buf)) # Peeking works after writing From 4d2f2dd147ab6813fae5ef03ef1377ed1dcf9893 Mon Sep 17 00:00:00 2001 From: Marcel Martin Date: Fri, 10 Apr 2026 23:41:33 +0200 Subject: [PATCH 30/30] Run clinic.py --- Modules/_io/bytesio.c | 2 +- Modules/_io/clinic/bytesio.c.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c index 84f0693f4626e7..d859104d547cf9 100644 --- a/Modules/_io/bytesio.c +++ b/Modules/_io/bytesio.c @@ -522,7 +522,7 @@ Return an empty bytes object at EOF. static PyObject * _io_BytesIO_peek_impl(bytesio *self, Py_ssize_t size) -/*[clinic end generated code: output=fa4d8ce28b35db9b input=cb06614a3ed0496e]*/ +/*[clinic end generated code: output=fa4d8ce28b35db9b input=1510f0fcf77c0048]*/ { CHECK_CLOSED(self); diff --git a/Modules/_io/clinic/bytesio.c.h b/Modules/_io/clinic/bytesio.c.h index 195eaca5ca14a4..ac7dd8733b6fff 100644 --- a/Modules/_io/clinic/bytesio.c.h +++ b/Modules/_io/clinic/bytesio.c.h @@ -683,4 +683,4 @@ _io_BytesIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=02299ed558ba722f input=a9049054013a1b77]*/ +/*[clinic end generated code: output=396250eb9869a0b4 input=a9049054013a1b77]*/