[pypy-svn] pypy collections-module: __reversed__().

arigo commits-noreply at bitbucket.org
Tue Feb 15 17:58:45 CET 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: collections-module
Changeset: r41982:5ae43fa4657b
Date: 2011-02-15 17:49 +0100
http://bitbucket.org/pypy/pypy/changeset/5ae43fa4657b/

Log:	__reversed__().

diff --git a/pypy/module/_collections/test/test_deque.py b/pypy/module/_collections/test/test_deque.py
--- a/pypy/module/_collections/test/test_deque.py
+++ b/pypy/module/_collections/test/test_deque.py
@@ -252,17 +252,9 @@
         assert d == e
 
     def test_reversed(self):
-        for s in ('abcd', xrange(2000)):
-            self.assertEqual(list(reversed(deque(s))), list(reversed(s)))
-
-    def test_gc_doesnt_blowup(self):
-        import gc
-        # This used to assert-fail in deque_traverse() under a debug
-        # build, or run wild with a NULL pointer in a release build.
-        d = deque()
-        for i in xrange(100):
-            d.append(1)
-            gc.collect()
+        from _collections import deque
+        for s in ('abcd', xrange(200)):
+            assert list(reversed(deque(s))) == list(reversed(s))
 
     def test_container_iterator(self):
         # Bug #3680: tp_traverse was not implemented for deque iterator objects

diff --git a/pypy/module/_collections/interp_deque.py b/pypy/module/_collections/interp_deque.py
--- a/pypy/module/_collections/interp_deque.py
+++ b/pypy/module/_collections/interp_deque.py
@@ -307,6 +307,10 @@
         return W_DequeIter(self)
 
     @unwrap_spec('self')
+    def reviter(self):
+        return W_DequeRevIter(self)
+
+    @unwrap_spec('self')
     def length(self):
         return self.space.wrap(self.len)
 
@@ -465,6 +469,7 @@
     rotate     = interp2app(W_Deque.rotate),
     __weakref__ = make_weakref_descr(W_Deque),
     __iter__ = interp2app(W_Deque.iter),
+    __reversed__ = interp2app(W_Deque.reviter),
     __len__ = interp2app(W_Deque.length),
     __repr__ = interp2app(W_Deque.repr),
     __lt__ = interp2app(W_Deque.lt),
@@ -520,3 +525,40 @@
 W_DequeIter.typedef.acceptable_as_base_class = False
 
 # ------------------------------------------------------------
+
+class W_DequeRevIter(Wrappable):
+    def __init__(self, deque):
+        self.space = deque.space
+        self.deque = deque
+        self.block = deque.rightblock
+        self.index = deque.rightindex
+        self.counter = deque.len
+        self.lock = deque.getlock()
+        check_nonneg(self.index)
+
+    @unwrap_spec('self')
+    def iter(self):
+        return self.space.wrap(self)
+
+    @unwrap_spec('self')
+    def next(self):
+        self.deque.checklock(self.lock)
+        if self.counter == 0:
+            raise OperationError(self.space.w_StopIteration, self.space.w_None)
+        self.counter -= 1
+        ri = self.index
+        w_x = self.block.data[ri]
+        ri -= 1
+        if ri < 0:
+            self.block = self.block.leftlink
+            ri = BLOCKLEN - 1
+        self.index = ri
+        return w_x
+
+W_DequeRevIter.typedef = TypeDef("deque_reverse_iterator",
+    __iter__ = interp2app(W_DequeRevIter.iter),
+    next = interp2app(W_DequeRevIter.next),
+)
+W_DequeRevIter.typedef.acceptable_as_base_class = False
+
+# ------------------------------------------------------------


More information about the Pypy-commit mailing list