Skip to content

Commit

Permalink
Added MemoryIO.writelines
Browse files Browse the repository at this point in the history
Signed-off-by: Andrea Zoppi <[email protected]>
  • Loading branch information
TexZK committed Dec 7, 2023
1 parent bf71529 commit 6d37058
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 9 deletions.
1 change: 1 addition & 0 deletions docs/reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ Reference
bytesparse
bytesparse.base
bytesparse.inplace
bytesparse.io
56 changes: 47 additions & 9 deletions src/bytesparse/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
r"""Streaming utilities."""

import io
from typing import Iterable
from typing import Iterator
from typing import List
from typing import Optional
Expand Down Expand Up @@ -86,10 +87,14 @@ class MemoryIO(io.BufferedIOBase):
The current stream position.
It always refers to absolute address 0.
_writable (bool):
The stream is writable on creation.
See Also:
:class:`ImmutableMemory`
:class:`MutableMemory`
:class:`bytesparse.base.ImmutableMemory`
:class:`bytesparse.base.MutableMemory`
:meth:`seek`
:meth:`writable`
Examples:
>>> from bytesparse import Memory, MemoryIO
Expand Down Expand Up @@ -1359,20 +1364,20 @@ def write(
The behaviour depends on the nature of `buffer`: byte-like or integer.
Byte-like data are written into the underlying memory object via its
:meth:`MutableMemory.write` method, at the current stream position
:meth:`bytesparse.base.MutableMemory.write` method, at the current stream position
(i.e. :meth:`tell`).
The stream position is always incremented by the size of `buffer`,
regardless of the actual number of bytes written into the
underlying memory object (e.g. when cropped by existing
:attr:`MutableMemory.bounds_span` settings).
:attr:`bytesparse.base.MutableMemory.bounds_span` settings).
If `buffer` is a positive integer, that is the amount of bytes to
:meth:`MutableMemory.clear` from the current stream position onwards.
:meth:`bytesparse.base.MutableMemory.clear` from the current stream position onwards.
The stream position is incremented by `buffer` bytes.
It returns `buffer` as a positive number.
If `buffer` is a negative integer, that is the amount of bytes to
:meth:`MutableMemory.delete` from the current stream position onwards.
:meth:`bytesparse.base.MutableMemory.delete` from the current stream position onwards.
The stream position is not changed.
It returns `buffer` as a positive number.
Expand All @@ -1391,9 +1396,9 @@ def write(
:exc:`io.UnsupportedOperation`: Stream not writable.
See Also:
:meth:`MutableMemory.clear`
:meth:`MutableMemory.delete`
:meth:`MutableMemory.write`
:meth:`bytesparse.base.MutableMemory.clear`
:meth:`bytesparse.base.MutableMemory.delete`
:meth:`bytesparse.base.MutableMemory.write`
Examples:
>>> from bytesparse import Memory, MemoryIO
Expand Down Expand Up @@ -1454,3 +1459,36 @@ def write(
return size
else:
raise io.UnsupportedOperation('not writable')

def writelines(
self,
lines: Iterable[Union[AnyBytes, int]],
) -> None:
r""" Writes lines to the stream.
Line separators are not added, so it is usual for each of the lines
provided to have a line separator at the end.
If a `line` is an integer, its behavior is as per :meth:`write`
(positive: clear, negative: delete).
Arguments:
lines (list of bytes):
List of byte strings to write.
See Also:
:meth:`bytesparse.base.MutableMemory.clear`
:meth:`bytesparse.base.MutableMemory.delete`
:meth:`write`
Examples:
>>> from bytesparse import Memory, MemoryIO
>>> lines = [3, b'Hello\n', b'World!', 5, b'Bye\n', 4, b'Bye!']
>>> stream = MemoryIO()
>>> stream.writelines(lines)
>>> stream.memory.to_blocks()
[[3, b'Hello\nWorld!'], [20, b'Bye\n'], [28, b'Bye!']]
"""

for line in lines:
self.write(line)
7 changes: 7 additions & 0 deletions tests/test_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -434,3 +434,10 @@ def test_write_fail(self):
with MemoryIO(memory) as stream:
with pytest.raises(io.UnsupportedOperation, match='not writable'):
stream.write(b'')

def test_writelines_doctest(self):
lines = [3, b'Hello\n', b'World!', 5, b'Bye\n', 4, b'Bye!']
stream = MemoryIO()
assert stream.writelines(lines) is None
ref = [[3, b'Hello\nWorld!'], [20, b'Bye\n'], [28, b'Bye!']]
assert stream.memory.to_blocks() == ref

0 comments on commit 6d37058

Please sign in to comment.