[pypy-commit] pypy set-strategies: refactored discard/delitem and wrote some more tests
l.diekmann
noreply at buildbot.pypy.org
Thu Nov 10 13:50:08 CET 2011
Author: Lukas Diekmann <lukas.diekmann at uni-duesseldorf.de>
Branch: set-strategies
Changeset: r49179:0b43c3756798
Date: 2011-05-25 14:56 +0200
http://bitbucket.org/pypy/pypy/changeset/0b43c3756798/
Log: refactored discard/delitem and wrote some more tests
diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py
--- a/pypy/objspace/std/setobject.py
+++ b/pypy/objspace/std/setobject.py
@@ -225,7 +225,7 @@
w_set.add(w_key)
def delitem(self, w_set, w_item):
- raise KeyError
+ return False
def discard(self, w_set, w_item):
return False
@@ -321,53 +321,17 @@
w_set.add(w_key)
def delitem(self, w_set, w_item):
- # not a normal set operation; only used internally
d = self.cast_from_void_star(w_set.sstorage)
+ if not self.is_correct_type(w_item):
+ w_set.switch_to_object_strategy(self.space)
+ return w_set.delitem(w_item)
+
+ key = self.unwrap(w_item)
try:
- del d[self.unwrap(w_item)]
- except KeyError:
- raise
-
- def discard(self, w_set, w_item):
- from pypy.objspace.std.dictmultiobject import _is_sane_hash
- d = self.cast_from_void_star(w_set.sstorage)
- try:
- del d[self.unwrap(w_item)]
+ del d[key]
return True
except KeyError:
return False
- except OperationError, e:
- # raise any error except TypeError
- if not e.match(self.space, self.space.w_TypeError):
- raise
- # if error is TypeError and w_item is not None, Int, String, Bool or Float
- # (i.e. FakeObject) switch to object strategy and discard again
- if (not _is_sane_hash(self.space, w_item) and
- self is not self.space.fromcache(ObjectSetStrategy)):
- w_set.switch_to_object_strategy(self.space)
- return w_set.discard(w_item)
- # else we have two cases:
- # - w_item is as set: then we convert it to frozenset and check again
- # - type doesn't match (string in intstrategy): then we raise (cause w_f is none)
- w_f = _convert_set_to_frozenset(self.space, w_item)
- if w_f is None:
- raise
-
- # if w_item is a set and we are not in ObjectSetStrategy we are finished here
- if not self.space.fromcache(ObjectSetStrategy):
- return False
-
- try:
- del d[w_f] # XXX nonsense in intstrategy
- return True
- except KeyError:
- return False
- except OperationError, e:
- #XXX is this ever tested?
- assert False
- if not e.match(space, space.w_TypeError):
- raise
- return False
def getdict_w(self, w_set):
result = newset(self.space)
@@ -821,10 +785,7 @@
w_left.difference_update(w_other)
else:
for w_key in space.listview(w_other):
- try:
- w_left.delitem(w_key)
- except KeyError:
- pass
+ w_left.delitem(w_key)
def inplace_sub__Set_Set(space, w_left, w_other):
w_left.difference_update(w_other)
@@ -974,10 +935,20 @@
frozenset if the argument is a set.
Returns True if successfully removed.
"""
- x = w_left.discard(w_item)
+ try:
+ deleted = w_left.delitem(w_item)
+ except OperationError, e:
+ if not e.match(space, space.w_TypeError):
+ raise
+ else:
+ w_f = _convert_set_to_frozenset(space, w_item)
+ if w_f is None:
+ raise
+ deleted = w_left.delitem(w_f)
+
if w_left.length() == 0:
w_left.switch_to_empty_strategy()
- return x
+ return deleted
def set_discard__Set_ANY(space, w_left, w_item):
_discard_from_set(space, w_left, w_item)
diff --git a/pypy/objspace/std/test/test_setobject.py b/pypy/objspace/std/test/test_setobject.py
--- a/pypy/objspace/std/test/test_setobject.py
+++ b/pypy/objspace/std/test/test_setobject.py
@@ -14,6 +14,7 @@
from pypy.objspace.std.setobject import and__Set_Set
from pypy.objspace.std.setobject import set_intersection__Set
from pypy.objspace.std.setobject import eq__Set_Set
+from pypy.conftest import gettestobjspace
letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
@@ -58,6 +59,28 @@
class AppTestAppSetTest:
+ def setup_class(self):
+ self.space = gettestobjspace()
+ w_fakeint = self.space.appexec([], """():
+ class FakeInt(object):
+ def __init__(self, value):
+ self.value = value
+ def __hash__(self):
+ return hash(self.value)
+
+ def __eq__(self, other):
+ if other == self.value:
+ return True
+ return False
+ return FakeInt
+ """)
+ self.w_FakeInt = w_fakeint
+
+ def test_fakeint(self):
+ f1 = self.FakeInt(4)
+ assert f1 == 4
+ assert hash(f1) == hash(4)
+
def test_simple(self):
a = set([1,2,3])
b = set()
@@ -546,52 +569,77 @@
yield i
set([1,2,3,4,5]).issuperset(foo())
+ def test_fakeint_and_equals(self):
+ s1 = set([1,2,3,4])
+ s2 = set([1,2,self.FakeInt(3), 4])
+ assert s1 == s2
- def test_fakeint_intstrategy(self):
- class FakeInt(object):
+ def test_fakeint_and_discard(self):
+ # test with object strategy
+ s = set([1, 2, 'three', 'four'])
+ s.discard(self.FakeInt(2))
+ assert s == set([1, 'three', 'four'])
+
+ s.remove(self.FakeInt(1))
+ assert s == set(['three', 'four'])
+ raises(KeyError, s.remove, self.FakeInt(16))
+
+ # test with int strategy
+ s = set([1,2,3,4])
+ s.discard(self.FakeInt(4))
+ assert s == set([1,2,3])
+ s.remove(self.FakeInt(3))
+ assert s == set([1,2])
+ raises(KeyError, s.remove, self.FakeInt(16))
+
+ def test_fakeobject_and_has_key(self):
+ s = set([1,2,3,4,5])
+ assert 5 in s
+ assert self.FakeInt(5) in s
+
+ def test_fakeobject_and_pop(self):
+ s = set([1,2,3,self.FakeInt(4), 5])
+ assert s.pop()
+ assert s.pop()
+ assert s.pop()
+ assert s.pop()
+ assert s.pop()
+ assert s == set([])
+
+ def test_fakeobject_and_difference(self):
+ s = set([1,2,'3',4])
+ s.difference_update([self.FakeInt(1), self.FakeInt(2)])
+ assert s == set(['3',4])
+
+ s = set([1,2,3,4])
+ s.difference_update([self.FakeInt(1), self.FakeInt(2)])
+ assert s == set([3,4])
+
+ def test_frozenset_behavior(self):
+ s = set([1,2,3,frozenset([4])])
+ raises(TypeError, s.difference_update, [1,2,3,set([4])])
+
+ s = set([1,2,3,frozenset([4])])
+ s.discard(set([4]))
+ assert s == set([1,2,3])
+
+ def test_discard_unhashable(self):
+ s = set([1,2,3,4])
+ raises(TypeError, s.discard, [1])
+
+
+ def test_discard_evil_compare(self):
+ class Evil(object):
def __init__(self, value):
self.value = value
def __hash__(self):
return hash(self.value)
-
def __eq__(self, other):
+ if isinstance(other, frozenset):
+ raise TypeError
if other == self.value:
return True
return False
+ s = set([1,2, Evil(frozenset([1]))])
+ raises(TypeError, s.discard, set([1]))
- f1 = FakeInt(4)
- assert f1 == 4
- assert hash(f1) == hash(4)
-
- # test with object strategy
- s = set([1, 2, 'three', 'four'])
- s.discard(FakeInt(2))
- assert s == set([1, 'three', 'four'])
- s.remove(FakeInt(1))
- assert s == set(['three', 'four'])
- raises(KeyError, s.remove, FakeInt(16))
-
- # test with int strategy
- s = set([1,2,3,4])
- s.discard(FakeInt(4))
- assert s == set([1,2,3])
- s.remove(FakeInt(3))
- assert s == set([1,2])
- raises(KeyError, s.remove, FakeInt(16))
-
-
- def test_fakeobject_and_has_key(test):
- class FakeInt(object):
- def __init__(self, value):
- self.value = value
- def __hash__(self):
- return hash(self.value)
-
- def __eq__(self, other):
- if other == self.value:
- return True
- return False
-
- s = set([1,2,3,4,5])
- assert 5 in s
- assert FakeInt(5) in s
More information about the pypy-commit
mailing list