Skip to content

Commit

Permalink
Implement BytesIO.peek()
Browse files Browse the repository at this point in the history
  • Loading branch information
marcelm committed Aug 5, 2022
1 parent a302a27 commit c755c4a
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 1 deletion.
8 changes: 8 additions & 0 deletions Lib/_pyio.py
Original file line number Diff line number Diff line change
Expand Up @@ -993,6 +993,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")
Expand Down
17 changes: 17 additions & 0 deletions Lib/test/test_memoryio.py
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,23 @@ def test_relative_seek(self):
memio.seek(1, 1)
self.assertEqual(memio.read(), buf[1:])

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()

Expand Down
37 changes: 37 additions & 0 deletions Modules/_io/bytesio.c
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,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]
_io.BytesIO.readline
size: Py_ssize_t(accept={int, NoneType}) = -1
Expand Down Expand Up @@ -1014,6 +1050,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
Expand Down
38 changes: 37 additions & 1 deletion Modules/_io/clinic/bytesio.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit c755c4a

Please sign in to comment.