Skip to content

Commit 07d9e4d

Browse files
committed
Default to size=0; cap to DEFAULT_BUFFER_SIZE
1 parent abbd8f0 commit 07d9e4d

5 files changed

Lines changed: 24 additions & 17 deletions

File tree

Doc/library/io.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -739,13 +739,13 @@ than raw I/O does.
739739

740740
Return :class:`bytes` containing the entire contents of the buffer.
741741

742-
.. method:: peek(size=1, /)
742+
.. method:: peek(size=0, /)
743743

744744
Return bytes from the current position onwards without advancing the position.
745745
At least one byte of data is returned if not at EOF.
746746
Return an empty :class:`bytes` object at EOF.
747-
If the size argument is less than one or larger than the number of available bytes,
748-
a copy of the buffer from the current position until the end is returned.
747+
The number of read bytes depends on the buffer size
748+
and the current position in the internal buffer.
749749

750750
.. versionadded:: 3.15
751751

Lib/_pyio.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -996,12 +996,12 @@ def tell(self):
996996
raise ValueError("tell on closed file")
997997
return self._pos
998998

999-
def peek(self, size=1):
999+
def peek(self, size=0):
10001000
if self.closed:
10011001
raise ValueError("peek on closed file")
10021002
if size < 1:
1003-
return self._buffer[self._pos:]
1004-
return self._buffer[self._pos:self._pos + size]
1003+
return self._buffer[self._pos:self._pos + DEFAULT_BUFFER_SIZE]
1004+
return self._buffer[self._pos:self._pos + min(size, DEFAULT_BUFFER_SIZE)]
10051005

10061006
def truncate(self, pos=None):
10071007
if self.closed:

Lib/test/test_io/test_memoryio.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,7 @@ def test_peek(self):
572572
self.assertEqual(memio.tell(), 0)
573573
self.assertEqual(memio.peek(1), buf[:1])
574574
self.assertEqual(memio.peek(1), buf[:1])
575-
self.assertEqual(memio.peek(), buf[:1])
575+
self.assertEqual(memio.peek(), buf)
576576
self.assertEqual(memio.peek(3), buf[:3])
577577
self.assertEqual(memio.peek(5), buf[:5])
578578
self.assertEqual(memio.peek(0), buf)
@@ -583,7 +583,7 @@ def test_peek(self):
583583
memio.read(1)
584584
self.assertEqual(memio.tell(), 1)
585585
self.assertEqual(memio.peek(1), buf[1:2])
586-
self.assertEqual(memio.peek(), buf[1:2])
586+
self.assertEqual(memio.peek(), buf[1:])
587587
self.assertEqual(memio.peek(3), buf[1:4])
588588
self.assertEqual(memio.peek(5), buf[1:6])
589589
self.assertEqual(memio.peek(0), buf[1:])
@@ -604,11 +604,17 @@ def test_peek(self):
604604
memio.write(abc)
605605
self.assertEqual(memio.peek(), self.EOF)
606606
memio.seek(len(buf))
607-
self.assertEqual(memio.peek(), abc[:1])
607+
self.assertEqual(memio.peek(), abc)
608608
self.assertEqual(memio.peek(-1), abc)
609609
self.assertEqual(memio.peek(len(abc) + 100), abc)
610610
self.assertEqual(memio.tell(), len(buf))
611611

612+
# Length of returned bytes object is capped to DEFAULT_BUFFER_SIZE
613+
buf = self.buftype("a" * (io.DEFAULT_BUFFER_SIZE + 10))
614+
with self.ioclass(buf) as memio:
615+
self.assertEqual(len(memio.peek()), io.DEFAULT_BUFFER_SIZE)
616+
self.assertEqual(len(memio.peek(io.DEFAULT_BUFFER_SIZE + 1)), io.DEFAULT_BUFFER_SIZE)
617+
612618
with self.ioclass(buf) as memio:
613619
memio.seek(len(buf))
614620
self.assertEqual(memio.peek(), self.EOF)

Modules/_io/bytesio.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -513,26 +513,28 @@ _io_BytesIO_read1_impl(bytesio *self, Py_ssize_t size)
513513
/*[clinic input]
514514
@critical_section
515515
_io.BytesIO.peek
516-
size: Py_ssize_t = 1
516+
size: Py_ssize_t = 0
517517
/
518518
519519
Return bytes from the stream without advancing the position.
520520
521-
If the size argument is zero or negative, read until EOF is reached.
522521
Return an empty bytes object at EOF.
523522
[clinic start generated code]*/
524523

525524
static PyObject *
526525
_io_BytesIO_peek_impl(bytesio *self, Py_ssize_t size)
527-
/*[clinic end generated code: output=fa4d8ce28b35db9b input=36dc9805d333fe24]*/
526+
/*[clinic end generated code: output=fa4d8ce28b35db9b input=2ce74234b10aec3e]*/
528527
{
529528
CHECK_CLOSED(self);
530529

531530
/* adjust invalid sizes */
532531
Py_ssize_t n = self->string_size - self->pos;
532+
if (n > DEFAULT_BUFFER_SIZE) {
533+
n = DEFAULT_BUFFER_SIZE;
534+
}
533535
if (size < 1 || size > n) {
534536
size = n;
535-
/* size can be negative after truncate() or seek() */
537+
/* n can be negative after truncate() or seek() */
536538
if (size < 0) {
537539
size = 0;
538540
}

Modules/_io/clinic/bytesio.c.h

Lines changed: 3 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)