Author: Brian Kearns <bdkea...@gmail.com> 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 pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit