[pypy-commit] pypy set-strategies: fix and tests for fakeints in instrategy

l.diekmann noreply at buildbot.pypy.org
Thu Nov 10 13:50:05 CET 2011


Author: Lukas Diekmann <lukas.diekmann at uni-duesseldorf.de>
Branch: set-strategies
Changeset: r49177:1e8aabff9f2a
Date: 2011-05-24 15:24 +0200
http://bitbucket.org/pypy/pypy/changeset/1e8aabff9f2a/

Log:	fix and tests for fakeints in instrategy

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
@@ -329,6 +329,7 @@
             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)]
@@ -336,13 +337,28 @@
         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]
+            del d[w_f] # XXX nonsense in intstrategy
             return True
         except KeyError:
             return False
@@ -595,7 +611,7 @@
     cast_from_void_star = staticmethod(cast_from_void_star)
 
     def get_empty_storage(self):
-        return self.cast_to_void_star(newset(self.space))
+        return self.cast_to_void_star(self.get_empty_dict())
 
     def get_empty_dict(self):
         return newset(self.space)
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
@@ -545,3 +545,36 @@
             for i in [1,2,3]:
                 yield i
         set([1,2,3,4,5]).issuperset(foo())
+
+
+    def test_fakeint_intstrategy(self):
+        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
+
+        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))


More information about the pypy-commit mailing list