Author: Philip Jenvey <pjen...@underboss.org> Branch: stdlib-2.7.12 Changeset: r87520:b6a910081211 Date: 2016-10-01 17:27 -0700 http://bitbucket.org/pypy/pypy/changeset/b6a910081211/
Log: ensure reversed types always free their sequence when finished diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py --- a/pypy/module/__builtin__/functional.py +++ b/pypy/module/__builtin__/functional.py @@ -371,6 +371,7 @@ # Done self.remaining = -1 + self.w_sequence = None raise OperationError(space.w_StopIteration, space.w_None) def descr___reduce__(self, space): diff --git a/pypy/objspace/std/iterobject.py b/pypy/objspace/std/iterobject.py --- a/pypy/objspace/std/iterobject.py +++ b/pypy/objspace/std/iterobject.py @@ -147,17 +147,21 @@ return self def descr_next(self, space): - if self.w_seq is None or self.index < 0: - raise OperationError(space.w_StopIteration, space.w_None) - try: - w_item = space.getitem(self.w_seq, space.wrap(self.index)) - self.index -= 1 - except OperationError as e: - self.w_seq = None - if not e.match(space, space.w_IndexError): - raise - raise OperationError(space.w_StopIteration, space.w_None) - return w_item + if self.index >= 0: + w_index = space.wrap(self.index) + try: + w_item = space.getitem(self.w_seq, w_index) + except OperationError as e: + if not e.match(space, space.w_IndexError): + raise + else: + self.index -= 1 + return w_item + + # Done + self.index = -1 + self.w_seq = None + raise OperationError(space.w_StopIteration, space.w_None) W_ReverseSeqIterObject.typedef = TypeDef( "reversesequenceiterator", diff --git a/pypy/objspace/std/test/test_iterobject.py b/pypy/objspace/std/test/test_iterobject.py --- a/pypy/objspace/std/test/test_iterobject.py +++ b/pypy/objspace/std/test/test_iterobject.py @@ -90,6 +90,18 @@ raises(TypeError, len, reversed(iterable)) del sys.modules['collections'] + def test_reversed_frees_empty(self): + import gc + for typ in list, unicode: + free = [False] + class U(typ): + def __del__(self): + free[0] = True + r = reversed(U()) + raises(StopIteration, next, r) + gc.collect(); gc.collect(); gc.collect() + assert free[0] + def test_no_len_on_set_iter(self): iterable = set([1,2,3,4]) raises(TypeError, len, iter(iterable)) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit