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

arigo commits-noreply at bitbucket.org
Tue Feb 15 16:02:48 CET 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: collections-module
Changeset: r41965:70352f1caae2
Date: 2011-02-15 14:18 +0100
http://bitbucket.org/pypy/pypy/changeset/70352f1caae2/

Log:	count().

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
@@ -79,10 +79,10 @@
 
     def test_count(self):
         from _collections import deque
-        for s in ('', 'abracadabra', 'simsalabim'*500+'abc'):
+        for s in ('', 'abracadabra', 'simsalabim'*50+'abc'):
             s = list(s)
             d = deque(s)
-            for letter in 'abcdefghijklmnopqrstuvwxyz':
+            for letter in 'abcdeilmrs':
                 assert s.count(letter) == d.count(letter)
         class MutatingCompare:
             def __eq__(self, other):

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
@@ -47,6 +47,9 @@
         self.rightlink = rightlink
         self.data = [None] * BLOCKLEN
 
+class Lock(object):
+    pass
+
 # ------------------------------------------------------------
 
 class W_Deque(Wrappable):
@@ -67,12 +70,17 @@
     def modified(self):
         self.lock = None
 
-    def getlock(self, iterator):
+    def getlock(self):
         if self.lock is None:
-            self.lock = iterator     # actually use the iterator itself,
-                                     # instead of some new empty object
+            self.lock = Lock()
         return self.lock
 
+    def checklock(self, lock):
+        if lock is not self.lock:
+            raise OperationError(
+                self.space.w_RuntimeError,
+                self.space.wrap("deque mutated during iteration"))
+
     @unwrap_spec('self', W_Root, W_Root)
     def init(self, w_iterable=NoneNotWrapped, w_maxlen=None):
         space = self.space
@@ -134,6 +142,25 @@
         self.modified()
 
     @unwrap_spec('self', W_Root)
+    def count(self, w_x):
+        space = self.space
+        result = 0
+        block = self.leftblock
+        index = self.leftindex
+        lock = self.getlock()
+        for i in range(self.len):
+            w_item = block.data[index]
+            if space.eq_w(w_item, w_x):
+                result += 1
+            self.checklock(lock)
+            # Advance the block/index pair
+            index += 1
+            if index >= BLOCKLEN:
+                block = block.rightlink
+                index = 0
+        return space.wrap(result)
+
+    @unwrap_spec('self', W_Root)
     def extend(self, w_iterable):
         # XXX Handle case where id(deque) == id(iterable)
         space = self.space
@@ -268,6 +295,7 @@
     append     = interp2app(W_Deque.append),
     appendleft = interp2app(W_Deque.appendleft),
     clear      = interp2app(W_Deque.clear),
+    count      = interp2app(W_Deque.count),
     extend     = interp2app(W_Deque.extend),
     extendleft = interp2app(W_Deque.extendleft),
     pop        = interp2app(W_Deque.pop),
@@ -288,7 +316,7 @@
         self.block = deque.leftblock
         self.index = deque.leftindex
         self.counter = deque.len
-        self.lock = deque.getlock(self)
+        self.lock = deque.getlock()
         check_nonneg(self.index)
 
     @unwrap_spec('self')
@@ -297,10 +325,7 @@
 
     @unwrap_spec('self')
     def next(self):
-        if self.lock is not self.deque.lock:
-            raise OperationError(
-                self.space.w_RuntimeError,
-                self.space.wrap("deque mutated during iteration"))
+        self.deque.checklock(self.lock)
         if self.counter == 0:
             raise OperationError(self.space.w_StopIteration, self.space.w_None)
         self.counter -= 1


More information about the Pypy-commit mailing list