Author: Brian Kearns <[email protected]>
Branch: stdlib-2.7.8
Changeset: r73022:5a56be10c6e7
Date: 2014-08-24 10:55 -0400
http://bitbucket.org/pypy/pypy/changeset/5a56be10c6e7/
Log: have islice release reference to source iterator when exhausted
diff --git a/pypy/module/itertools/interp_itertools.py
b/pypy/module/itertools/interp_itertools.py
--- a/pypy/module/itertools/interp_itertools.py
+++ b/pypy/module/itertools/interp_itertools.py
@@ -391,16 +391,31 @@
# has no effect any more
if stop > 0:
self._ignore_items(stop)
+ self.iterable = None
raise OperationError(self.space.w_StopIteration,
self.space.w_None)
self.stop = stop - (ignore + 1)
if ignore > 0:
self._ignore_items(ignore)
- return self.space.next(self.iterable)
+ if self.iterable is None:
+ raise OperationError(self.space.w_StopIteration, self.space.w_None)
+ try:
+ return self.space.next(self.iterable)
+ except OperationError as e:
+ if e.match(self.space, self.space.w_StopIteration):
+ self.iterable = None
+ raise
def _ignore_items(self, num):
+ if self.iterable is None:
+ raise OperationError(self.space.w_StopIteration, self.space.w_None)
while True:
- self.space.next(self.iterable)
+ try:
+ self.space.next(self.iterable)
+ except OperationError as e:
+ if e.match(self.space, self.space.w_StopIteration):
+ self.iterable = None
+ raise
num -= 1
if num <= 0:
break
diff --git a/pypy/module/itertools/test/test_itertools.py
b/pypy/module/itertools/test/test_itertools.py
--- a/pypy/module/itertools/test/test_itertools.py
+++ b/pypy/module/itertools/test/test_itertools.py
@@ -237,6 +237,18 @@
assert list(itertools.islice(xrange(10), None,None)) == range(10)
assert list(itertools.islice(xrange(10), None,None,None)) == range(10)
+ # check source iterator is not referenced from islice()
+ # after the latter has been exhausted
+ import weakref
+ for args in [(1,), (None,), (0, None, 2)]:
+ it = (x for x in (1, 2, 3))
+ wr = weakref.ref(it)
+ it = itertools.islice(it, *args)
+ assert wr() is not None
+ list(it) # exhaust the iterator
+ assert wr() is None
+ raises(StopIteration, next, it)
+
def test_islice_dropitems_exact(self):
import itertools
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit