[pypy-commit] pypy stdlib-2.7.12: ensure reversed types always free their sequence when finished
pjenvey
pypy.commits at gmail.com
Sun Oct 2 13:37:17 EDT 2016
Author: Philip Jenvey <pjenvey at 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))
More information about the pypy-commit
mailing list