Author: Lukas Diekmann <[email protected]>
Branch: list-strategies
Changeset: r47547:89afe67415a7
Date: 2011-09-13 16:34 +0200
http://bitbucket.org/pypy/pypy/changeset/89afe67415a7/

Log:    deferred contains to strategies

diff --git a/pypy/objspace/std/listobject.py b/pypy/objspace/std/listobject.py
--- a/pypy/objspace/std/listobject.py
+++ b/pypy/objspace/std/listobject.py
@@ -107,6 +107,9 @@
         # XXX what is this used for?
         self.strategy.copy_into(self, other)
 
+    def contains(self, w_obj):
+        return self.strategy.contains(self, w_obj)
+
     def append(w_list, w_item):
         w_list.strategy.append(w_list, w_item)
 
@@ -175,6 +178,9 @@
     def copy_into(self, w_list, w_other):
         raise NotImplementedError
 
+    def contains(self, w_list, w_obj):
+        raise NotImplementedError
+
     def length(self, w_list):
         raise NotImplementedError
 
@@ -248,6 +254,9 @@
     def copy_into(self, w_list, w_other):
         pass
 
+    def contains(self, w_list, w_obj):
+        return self.space.w_False
+
     def length(self, w_list):
         return 0
 
@@ -335,6 +344,17 @@
         w_other.strategy = self
         w_other.lstorage = w_list.lstorage
 
+    def contains(self, w_list, w_obj):
+        if is_W_IntObject(w_obj):
+            start, step, length = self.unerase(w_list.lstorage)
+            obj = self.unwrap(w_obj)
+            i = start
+            while i < start + step * length:
+                if i == obj:
+                    return self.space.w_True
+                i += step
+        return self.space.w_False
+
     def length(self, w_list):
         return self.unerase(w_list.lstorage)[2]
 
@@ -512,6 +532,16 @@
         items = self.unerase(w_list.lstorage)[:]
         w_other.lstorage = self.erase(items)
 
+    def contains(self, w_list, w_obj):
+        if self.is_correct_type(w_obj):
+            obj = self.unwrap(w_obj)
+            l = self.unerase(w_list.lstorage)
+            #XXX why do I need to check mutation for eq_w?
+            for i in l:
+                if i == obj:
+                    return self.space.w_True
+        return self.space.w_False
+
     def length(self, w_list):
         return len(self.unerase(w_list.lstorage))
 
@@ -918,15 +948,7 @@
 
 def contains__List_ANY(space, w_list, w_obj):
     # needs to be safe against eq_w() mutating the w_list behind our back
-    # XXX we want to defer that to the list strategy, because it would be a lot
-    # more efficient to not call eq_w on ints. contains is used rather often 
in code like:
-    # if i in [1, 2, 3]: ...
-    i = 0
-    while i < w_list.length(): # intentionally always calling len!
-        if space.eq_w(w_list.getitem(i), w_obj):
-            return space.w_True
-        i += 1
-    return space.w_False
+    return w_list.contains(w_obj)
 
 def iter__List(space, w_list):
     from pypy.objspace.std import iterobject
diff --git a/pypy/objspace/std/test/test_listobject.py 
b/pypy/objspace/std/test/test_listobject.py
--- a/pypy/objspace/std/test/test_listobject.py
+++ b/pypy/objspace/std/test/test_listobject.py
@@ -353,6 +353,39 @@
         l2 = [1, "2", "a", "a"]
         assert sorted(l1) == sorted(l2)
 
+    def test_contains(self):
+        l = []
+        assert not l.__contains__(2)
+
+        l = [1,2,3]
+        assert l.__contains__(2)
+        assert not l.__contains__("2")
+
+        l = ["1","2","3"]
+        assert l.__contains__("2")
+        assert not l.__contains__(2)
+
+        l = range(4)
+        assert l.__contains__(2)
+        assert not l.__contains__("2")
+
+        l = [1,2,"3"]
+        assert l.__contains__(2)
+        assert not l.__contains__("2")
+
+        l = range(2, 20, 3) # = [2, 5, 8, 11, 14, 17]
+        assert l.__contains__(2)
+        assert l.__contains__(5)
+        assert l.__contains__(8)
+        assert l.__contains__(11)
+        assert l.__contains__(14)
+        assert l.__contains__(17)
+        assert not l.__contains__(3)
+        assert not l.__contains__(4)
+        assert not l.__contains__(7)
+        assert not l.__contains__(13)
+        assert not l.__contains__(20)
+
     def test_call_list(self):
         assert list('') == []
         assert list('abc') == ['a', 'b', 'c']
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to