[pypy-commit] pypy set-strategies: added fastpath for not comparable sets (starting with difference)

l.diekmann noreply at buildbot.pypy.org
Thu Nov 10 13:52:28 CET 2011


Author: Lukas Diekmann <lukas.diekmann at uni-duesseldorf.de>
Branch: set-strategies
Changeset: r49259:06b2d8982ba0
Date: 2011-11-02 17:40 +0100
http://bitbucket.org/pypy/pypy/changeset/06b2d8982ba0/

Log:	added fastpath for not comparable sets (starting with difference)

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
@@ -506,6 +506,9 @@
         if self is w_other.strategy:
             strategy = w_set.strategy
             storage = self._difference_unwrapped(w_set, w_other)
+        elif not_comparable(self.space, w_set.strategy, w_other.strategy):
+            strategy = w_set.strategy
+            storage = w_set.sstorage
         else:
             strategy = self.space.fromcache(ObjectSetStrategy)
             storage = self._difference_wrapped(w_set, w_other)
@@ -891,6 +894,17 @@
 
 # some helper functions
 
+def not_comparable(space, strategy1, strategy2):
+    # add all strategies here that cannot be compared. this way is safer than
+    # adding only types that can be compared. else we get wrong results if
+    # someone adds new strategies and forgets to define them here. since this
+    # is only a fastpath we want to avoid possible errors
+    if strategy1 is space.fromcache(StringSetStrategy) and strategy2 is space.fromcache(IntegerSetStrategy):
+        return True
+    if strategy1 is space.fromcache(EmptySetStrategy) or strategy2 is space.fromcache(EmptySetStrategy):
+        return True
+    return False
+
 def newset(space):
     return r_dict(space.eq_w, space.hash_w, force_non_null=True)
 
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
@@ -604,6 +604,12 @@
         x.symmetric_difference_update(set())
         assert x == set([1,2,3])
 
+    def test_difference_uncomparable_strategies(self):
+        a = set([1,2,3])
+        b = set(["a","b","c"])
+        assert a.difference(b) == a
+        assert b.difference(a) == b
+
     def test_empty_intersect(self):
         e = set()
         x = set([1,2,3])


More information about the pypy-commit mailing list