Author: Lukas Diekmann <lukas.diekm...@uni-duesseldorf.de>
Branch: set-strategies
Changeset: r50751:b0d872ae3261
Date: 2011-12-20 13:42 +0100
http://bitbucket.org/pypy/pypy/changeset/b0d872ae3261/

Log:    merged set- with liststrategies. when initializing a set with lists
        they can copy the storage and strategy from that list without
        wrapping the storages content

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
@@ -508,6 +508,11 @@
     def getitems_copy(self, w_list):
         return self._getitems_range(w_list, True)
 
+    getitems_wrapped = getitems_copy
+
+    def getitems_unwrapped(self, w_list):
+        return self._getitems_range(w_list, False)
+
     def getstorage_copy(self, w_list):
         # tuple is unmutable
         return w_list.lstorage
@@ -698,6 +703,11 @@
     def getitems_copy(self, w_list):
         return [self.wrap(item) for item in self.unerase(w_list.lstorage)]
 
+    getitems_wrapped = getitems_copy
+
+    def getitems_unwrapped(self, w_list):
+        return self.unerase(w_list.lstorage)
+
     @jit.unroll_safe
     def getitems_unroll(self, w_list):
         return [self.wrap(item) for item in self.unerase(w_list.lstorage)]
@@ -926,6 +936,8 @@
     def getitems(self, w_list):
         return self.unerase(w_list.lstorage)
 
+    getitems_wrapped = getitems
+
 class IntegerListStrategy(AbstractUnwrappedStrategy, ListStrategy):
     _none_value = 0
     _applevel_repr = "int"
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
@@ -13,6 +13,8 @@
 from pypy.objspace.std.listobject import W_ListObject
 from pypy.objspace.std.intobject import W_IntObject
 from pypy.objspace.std.stringobject import W_StringObject
+from pypy.objspace.std.listobject import IntegerListStrategy, 
StringListStrategy,\
+        EmptyListStrategy, RangeListStrategy, ObjectListStrategy, 
FloatListStrategy
 
 class W_BaseSetObject(W_Object):
     typedef = None
@@ -280,6 +282,9 @@
     def get_empty_storage(self):
         return self.erase(None)
 
+    def get_storage_from_w_list(self, w_list):
+        return self.get_empty_storage()
+
     def is_correct_type(self, w_key):
         return False
 
@@ -384,6 +389,14 @@
             setdata[self.unwrap(w_item)] = None
         return self.erase(setdata)
 
+    def get_storage_from_w_list(self, w_list):
+        items = w_list.strategy.getitems_unwrapped(w_list)
+
+        setdata = self.get_empty_dict()
+        for item in items:
+            setdata[item] = None
+        return self.erase(setdata)
+
     def length(self, w_set):
         return len(self.unerase(w_set.sstorage))
 
@@ -746,6 +759,14 @@
     def get_empty_storage(self):
         return self.erase(self.get_empty_dict())
 
+    def get_storage_from_w_list(self, w_list):
+        items = w_list.strategy.getitems_wrapped(w_list)
+
+        setdata = self.get_empty_dict()
+        for item in items:
+            setdata[item] = None
+        return self.erase(setdata)
+
     def get_empty_dict(self):
         return newset(self.space)
 
@@ -883,6 +904,22 @@
 def newset(space):
     return r_dict(space.eq_w, space.hash_w, force_non_null=True)
 
+_strategy_map = {
+    EmptyListStrategy: EmptySetStrategy,
+    IntegerListStrategy: IntegerSetStrategy,
+    RangeListStrategy: IntegerSetStrategy,
+    StringListStrategy: StringSetStrategy,
+    FloatListStrategy: ObjectSetStrategy,
+    ObjectListStrategy: ObjectSetStrategy
+}
+
+def set_strategy_and_setdata_from_listobject(space, w_set, w_list):
+    strategy_class = _strategy_map[w_list.strategy.__class__]
+    strategy = space.fromcache(strategy_class)
+
+    w_set.sstorage = strategy.get_storage_from_w_list(w_list)
+    w_set.strategy = strategy
+
 def set_strategy_and_setdata(space, w_set, w_iterable):
     from pypy.objspace.std.intobject import W_IntObject
     if w_iterable is None :
@@ -895,6 +932,10 @@
         w_set.sstorage = w_iterable.get_storage_copy()
         return
 
+    if isinstance(w_iterable, W_ListObject):
+        set_strategy_and_setdata_from_listobject(space, w_set, w_iterable)
+        return
+
     iterable_w = space.listview(w_iterable)
 
     if len(iterable_w) == 0:
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
@@ -8,7 +8,7 @@
 is not too wrong.
 """
 import py.test
-from pypy.objspace.std.setobject import W_SetObject, W_FrozensetObject
+from pypy.objspace.std.setobject import W_SetObject, W_FrozensetObject, 
IntegerSetStrategy
 from pypy.objspace.std.setobject import _initialize_set
 from pypy.objspace.std.setobject import newset
 from pypy.objspace.std.setobject import and__Set_Set
@@ -83,6 +83,45 @@
         result = set_intersection__Set(space, a, [d,c,b])
         assert space.is_true(self.space.eq(result, W_SetObject(space, 
self.space.wrap(""))))
 
+    def test_create_set_from_list(self):
+        from pypy.objspace.std.setobject import ObjectSetStrategy, 
StringSetStrategy
+        from pypy.objspace.std.floatobject import W_FloatObject
+        from pypy.objspace.std.model import W_Object
+
+        w = self.space.wrap
+        intstr = self.space.fromcache(IntegerSetStrategy)
+        tmp_func = intstr.get_storage_from_list
+        # test if get_storage_from_list is no longer used
+        intstr.get_storage_from_list = None
+
+        w_list = W_ListObject(self.space, [w(1), w(2), w(3)])
+        w_set = W_SetObject(self.space)
+        _initialize_set(self.space, w_set, w_list)
+        assert w_set.strategy is intstr
+        assert intstr.unerase(w_set.sstorage) == {1:None, 2:None, 3:None}
+
+        w_list = W_ListObject(self.space, [w("1"), w("2"), w("3")])
+        w_set = W_SetObject(self.space)
+        _initialize_set(self.space, w_set, w_list)
+        assert w_set.strategy is self.space.fromcache(StringSetStrategy)
+        assert w_set.strategy.unerase(w_set.sstorage) == {"1":None, "2":None, 
"3":None}
+
+        w_list = W_ListObject(self.space, [w("1"), w(2), w("3")])
+        w_set = W_SetObject(self.space)
+        _initialize_set(self.space, w_set, w_list)
+        assert w_set.strategy is self.space.fromcache(ObjectSetStrategy)
+        for item in w_set.strategy.unerase(w_set.sstorage):
+            assert isinstance(item, W_Object)
+
+        w_list = W_ListObject(self.space, [w(1.0), w(2.0), w(3.0)])
+        w_set = W_SetObject(self.space)
+        _initialize_set(self.space, w_set, w_list)
+        assert w_set.strategy is self.space.fromcache(ObjectSetStrategy)
+        for item in w_set.strategy.unerase(w_set.sstorage):
+            assert isinstance(item, W_FloatObject)
+
+        # changed cached object, need to change it back for other tests to pass
+        intstr.get_storage_from_list = tmp_func
 
 class AppTestAppSetTest:
 
diff --git a/pypy/objspace/std/test/test_setstrategies.py 
b/pypy/objspace/std/test/test_setstrategies.py
--- a/pypy/objspace/std/test/test_setstrategies.py
+++ b/pypy/objspace/std/test/test_setstrategies.py
@@ -5,7 +5,7 @@
 class TestW_SetStrategies:
 
     def wrapped(self, l):
-        return W_ListObject([self.space.wrap(x) for x in l])
+        return W_ListObject(self.space, [self.space.wrap(x) for x in l])
 
     def test_from_list(self):
         s = W_SetObject(self.space, self.wrapped([1,2,3,4,5]))
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to