Skip to content

Commit

Permalink
Merge 7c53a74 into b5700b4
Browse files Browse the repository at this point in the history
  • Loading branch information
bbayles committed Jan 2, 2020
2 parents b5700b4 + 7c53a74 commit 4fcdee0
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 6 deletions.
26 changes: 21 additions & 5 deletions more_itertools/more.py
Expand Up @@ -2121,9 +2121,6 @@ class seekable:
>>> next(it), next(it), next(it)
('0', '1', '2')
The cache grows as the source iterable progresses, so beware of wrapping
very large or infinite iterables.
You may view the contents of the cache with the :meth:`elements` method.
That returns a :class:`SequenceView`, a view that updates automatically:
Expand All @@ -2138,11 +2135,30 @@ class seekable:
>>> elements
SequenceView(['0', '1', '2', '3'])
By default, the cache grows as the source iterable progresses, so beware of
wrapping very large or infinite iterables. Supply *maxlen* to limit the
size of the cache (this of course limits how far back you can seek).
>>> from itertools import count
>>> it = seekable((str(n) for n in count()), maxlen=2)
>>> next(it), next(it), next(it), next(it)
('0', '1', '2', '3')
>>> list(it.elements())
['2', '3']
>>> it.seek(0)
>>> next(it), next(it), next(it), next(it)
('2', '3', '4', '5')
>>> next(it)
'6'
"""

def __init__(self, iterable):
def __init__(self, iterable, maxlen=None):
self._source = iter(iterable)
self._cache = []
if maxlen is None:
self._cache = []
else:
self._cache = deque([], maxlen)
self._index = None

def __iter__(self):
Expand Down
4 changes: 3 additions & 1 deletion more_itertools/more.pyi
Expand Up @@ -272,7 +272,9 @@ class SequenceView(Generic[_T], Sequence[_T]):
def __len__(self) -> int: ...

class seekable(Generic[_T], Iterator[_T]):
def __init__(self, iterable: Iterable[_T]) -> None: ...
def __init__(
self, iterable: Iterable[_T], maxlen: Optional[int] = ...
) -> None: ...
def __iter__(self) -> seekable[_T]: ...
def __next__(self) -> _T: ...
def elements(self) -> SequenceView[_T]: ...
Expand Down
17 changes: 17 additions & 0 deletions tests/test_more.py
Expand Up @@ -2245,6 +2245,23 @@ def test_elements(self):
mi.take(10, s)
self.assertEqual(list(elements), [str(n) for n in range(20)])

def test_maxlen(self):
iterable = map(str, count())

s = mi.seekable(iterable, maxlen=4)
self.assertEqual(mi.take(10, s), [str(n) for n in range(10)])
self.assertEqual(list(s.elements()), ['6', '7', '8', '9'])

s.seek(0)
self.assertEqual(mi.take(14, s), [str(n) for n in range(6, 20)])
self.assertEqual(list(s.elements()), ['16', '17', '18', '19'])

def test_maxlen_zero(self):
iterable = [str(x) for x in range(5)]
s = mi.seekable(iterable, maxlen=0)
self.assertEqual(list(s), iterable)
self.assertEqual(list(s.elements()), [])


class SequenceViewTests(TestCase):
def test_init(self):
Expand Down

0 comments on commit 4fcdee0

Please sign in to comment.