[pypy-commit] pypy list-strategies: need to use space.eq_w and be safe against mutating for objectlists
l.diekmann
noreply at buildbot.pypy.org
Fri Sep 23 13:15:30 CEST 2011
Author: Lukas Diekmann <lukas.diekmann at uni-duesseldorf.de>
Branch: list-strategies
Changeset: r47548:7e62a6e1516b
Date: 2011-09-14 11:47 +0200
http://bitbucket.org/pypy/pypy/changeset/7e62a6e1516b/
Log: need to use space.eq_w and be safe against mutating for objectlists
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
@@ -179,7 +179,13 @@
raise NotImplementedError
def contains(self, w_list, w_obj):
- raise NotImplementedError
+ # needs to be safe against eq_w() mutating the w_list behind our back
+ i = 0
+ while i < w_list.length(): # intentionally always calling len!
+ if self.space.eq_w(w_list.getitem(i), w_obj):
+ return True
+ i += 1
+ return False
def length(self, w_list):
raise NotImplementedError
@@ -255,7 +261,7 @@
pass
def contains(self, w_list, w_obj):
- return self.space.w_False
+ return False
def length(self, w_list):
return 0
@@ -349,11 +355,14 @@
start, step, length = self.unerase(w_list.lstorage)
obj = self.unwrap(w_obj)
i = start
+ #if 0 <= (obj - start) <= length * step and (obj - start) % step == 0:
+ # return True
while i < start + step * length:
if i == obj:
- return self.space.w_True
+ return True
i += step
- return self.space.w_False
+
+ return ListStrategy.contains(self, w_list, w_obj)
def length(self, w_list):
return self.unerase(w_list.lstorage)[2]
@@ -536,11 +545,10 @@
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
+ return True
+ return ListStrategy.contains(self, w_list, w_obj)
def length(self, w_list):
return len(self.unerase(w_list.lstorage))
@@ -773,6 +781,9 @@
def init_from_list_w(self, w_list, list_w):
w_list.lstorage = self.erase(list_w)
+ def contains(self, w_list, w_obj):
+ return ListStrategy.contains(self, w_list, w_obj)
+
def getitems(self, w_list):
return self.unerase(w_list.lstorage)
@@ -947,8 +958,7 @@
w_list.deleteslice(start, 1, stop-start)
def contains__List_ANY(space, w_list, w_obj):
- # needs to be safe against eq_w() mutating the w_list behind our back
- return w_list.contains(w_obj)
+ return space.wrap(w_list.contains(w_obj))
def iter__List(space, w_list):
from pypy.objspace.std import iterobject
@@ -959,7 +969,6 @@
w_clone.extend(w_list2)
return w_clone
-
def inplace_add__List_ANY(space, w_list1, w_iterable2):
try:
list_extend__List_ANY(space, w_list1, w_iterable2)
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
@@ -360,6 +360,7 @@
l = [1,2,3]
assert l.__contains__(2)
assert not l.__contains__("2")
+ assert l.__contains__(1.0)
l = ["1","2","3"]
assert l.__contains__("2")
@@ -845,6 +846,20 @@
l.remove(5)
assert l[10:] == [0, 1, 2, 3, 4, 6, 7, 8, 9]
+ def test_mutate_while_contains(self):
+ class Mean(object):
+ def __init__(self, i):
+ self.i = i
+ def __eq__(self, other):
+ if self.i == 9 == other:
+ del l[0]
+ return True
+ else:
+ return False
+ l = [Mean(i) for i in range(10)]
+ assert l.__contains__(9)
+ assert not l.__contains__(2)
+
def test_mutate_while_extend(self):
# this used to segfault pypy-c (with py.test -A)
import sys
More information about the pypy-commit
mailing list