[pypy-commit] pypy default: merge the unicode-strategies branch: it adds supports for unicode-opimized lists, dicts and sets

antocuni noreply at buildbot.pypy.org
Thu Nov 1 12:17:16 CET 2012


Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: 
Changeset: r58659:dd9f4ba048dc
Date: 2012-11-01 12:16 +0100
http://bitbucket.org/pypy/pypy/changeset/dd9f4ba048dc/

Log:	merge the unicode-strategies branch: it adds supports for unicode-
	opimized lists, dicts and sets

diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -953,6 +953,13 @@
         """
         return None
 
+    def listview_unicode(self, w_list):
+        """ Return a list of unwrapped unicode out of a list of unicode. If the
+        argument is not a list or does not contain only unicode, return None.
+        May return None anyway.
+        """
+        return None
+
     def view_as_kwargs(self, w_dict):
         """ if w_dict is a kwargs-dict, return two lists, one of unwrapped
         strings and one of wrapped values. otherwise return (None, None)
diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py
--- a/pypy/objspace/std/dictmultiobject.py
+++ b/pypy/objspace/std/dictmultiobject.py
@@ -113,7 +113,7 @@
                     getitem_str delitem length \
                     clear w_keys values \
                     items iterkeys itervalues iteritems setdefault \
-                    popitem listview_str listview_int".split()
+                    popitem listview_str listview_unicode listview_int".split()
 
     def make_method(method):
         def f(self, *args):
@@ -187,6 +187,9 @@
     def listview_str(self, w_dict):
         return None
 
+    def listview_unicode(self, w_dict):
+        return None
+
     def listview_int(self, w_dict):
         return None
 
@@ -207,6 +210,9 @@
         if type(w_key) is self.space.StringObjectCls:
             self.switch_to_string_strategy(w_dict)
             return
+        elif type(w_key) is self.space.UnicodeObjectCls:
+            self.switch_to_unicode_strategy(w_dict)
+            return
         w_type = self.space.type(w_key)
         if self.space.is_w(w_type, self.space.w_int):
             self.switch_to_int_strategy(w_dict)
@@ -221,6 +227,12 @@
         w_dict.strategy = strategy
         w_dict.dstorage = storage
 
+    def switch_to_unicode_strategy(self, w_dict):
+        strategy = self.space.fromcache(UnicodeDictStrategy)
+        storage = strategy.get_empty_storage()
+        w_dict.strategy = strategy
+        w_dict.dstorage = storage
+
     def switch_to_int_strategy(self, w_dict):
         strategy = self.space.fromcache(IntDictStrategy)
         storage = strategy.get_empty_storage()
@@ -625,6 +637,73 @@
 create_iterator_classes(StringDictStrategy)
 
 
+class UnicodeDictStrategy(AbstractTypedStrategy, DictStrategy):
+
+    erase, unerase = rerased.new_erasing_pair("unicode")
+    erase = staticmethod(erase)
+    unerase = staticmethod(unerase)
+
+    def wrap(self, unwrapped):
+        return self.space.wrap(unwrapped)
+
+    def unwrap(self, wrapped):
+        return self.space.unicode_w(wrapped)
+
+    def is_correct_type(self, w_obj):
+        space = self.space
+        return space.is_w(space.type(w_obj), space.w_unicode)
+
+    def get_empty_storage(self):
+        res = {}
+        mark_dict_non_null(res)
+        return self.erase(res)
+
+    def _never_equal_to(self, w_lookup_type):
+        return _never_equal_to_string(self.space, w_lookup_type)
+
+    # we should implement the same shortcuts as we do for StringDictStrategy
+
+    ## def setitem_str(self, w_dict, key, w_value):
+    ##     assert key is not None
+    ##     self.unerase(w_dict.dstorage)[key] = w_value
+
+    ## def getitem(self, w_dict, w_key):
+    ##     space = self.space
+    ##     # -- This is called extremely often.  Hack for performance --
+    ##     if type(w_key) is space.StringObjectCls:
+    ##         return self.getitem_str(w_dict, w_key.unwrap(space))
+    ##     # -- End of performance hack --
+    ##     return AbstractTypedStrategy.getitem(self, w_dict, w_key)
+
+    ## def getitem_str(self, w_dict, key):
+    ##     assert key is not None
+    ##     return self.unerase(w_dict.dstorage).get(key, None)
+
+    def listview_unicode(self, w_dict):
+        return self.unerase(w_dict.dstorage).keys()
+
+    ## def w_keys(self, w_dict):
+    ##     return self.space.newlist_str(self.listview_str(w_dict))
+
+    def wrapkey(space, key):
+        return space.wrap(key)
+
+    ## @jit.look_inside_iff(lambda self, w_dict:
+    ##                      w_dict_unrolling_heuristic(w_dict))
+    ## def view_as_kwargs(self, w_dict):
+    ##     d = self.unerase(w_dict.dstorage)
+    ##     l = len(d)
+    ##     keys, values = [None] * l, [None] * l
+    ##     i = 0
+    ##     for key, val in d.iteritems():
+    ##         keys[i] = key
+    ##         values[i] = val
+    ##         i += 1
+    ##     return keys, values
+
+create_iterator_classes(UnicodeDictStrategy)
+
+
 class IntDictStrategy(AbstractTypedStrategy, DictStrategy):
     erase, unerase = rerased.new_erasing_pair("int")
     erase = staticmethod(erase)
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
@@ -32,7 +32,8 @@
     storage = strategy.erase(None)
     return W_ListObject.from_storage_and_strategy(space, storage, strategy)
 
- at jit.look_inside_iff(lambda space, list_w, sizehint: jit.isconstant(len(list_w)) and len(list_w) < UNROLL_CUTOFF)
+ at jit.look_inside_iff(lambda space, list_w, sizehint:
+                         jit.isconstant(len(list_w)) and len(list_w) < UNROLL_CUTOFF)
 def get_strategy_from_list_objects(space, list_w, sizehint):
     if not list_w:
         if sizehint != -1:
@@ -53,6 +54,13 @@
     else:
         return space.fromcache(StringListStrategy)
 
+    # check for unicode
+    for w_obj in list_w:
+        if not is_W_UnicodeObject(w_obj):
+            break
+    else:
+        return space.fromcache(UnicodeListStrategy)
+
     # check for floats
     for w_obj in list_w:
         if not is_W_FloatObject(w_obj):
@@ -70,6 +78,10 @@
     from pypy.objspace.std.stringobject import W_StringObject
     return type(w_object) is W_StringObject
 
+def is_W_UnicodeObject(w_object):
+    from pypy.objspace.std.unicodeobject import W_UnicodeObject
+    return type(w_object) is W_UnicodeObject
+
 def is_W_FloatObject(w_object):
     from pypy.objspace.std.floatobject import W_FloatObject
     return type(w_object) is W_FloatObject
@@ -211,6 +223,11 @@
         not use the list strategy, return None. """
         return self.strategy.getitems_str(self)
 
+    def getitems_unicode(self):
+        """ Return the items in the list as unwrapped unicodes. If the list does
+        not use the list strategy, return None. """
+        return self.strategy.getitems_unicode(self)
+
     def getitems_int(self):
         """ Return the items in the list as unwrapped ints. If the list does
         not use the list strategy, return None. """
@@ -315,6 +332,9 @@
     def getitems_str(self, w_list):
         return None
 
+    def getitems_unicode(self, w_list):
+        return None
+
     def getitems_int(self, w_list):
         return None
 
@@ -419,6 +439,8 @@
             strategy = self.space.fromcache(IntegerListStrategy)
         elif is_W_StringObject(w_item):
             strategy = self.space.fromcache(StringListStrategy)
+        elif is_W_UnicodeObject(w_item):
+            strategy = self.space.fromcache(UnicodeListStrategy)
         elif is_W_FloatObject(w_item):
             strategy = self.space.fromcache(FloatListStrategy)
         else:
@@ -1036,6 +1058,37 @@
     def getitems_str(self, w_list):
         return self.unerase(w_list.lstorage)
 
+
+class UnicodeListStrategy(AbstractUnwrappedStrategy, ListStrategy):
+    _none_value = None
+    _applevel_repr = "unicode"
+
+    def wrap(self, stringval):
+        return self.space.wrap(stringval)
+
+    def unwrap(self, w_string):
+        return self.space.unicode_w(w_string)
+
+    erase, unerase = rerased.new_erasing_pair("unicode")
+    erase = staticmethod(erase)
+    unerase = staticmethod(unerase)
+
+    def is_correct_type(self, w_obj):
+        return is_W_UnicodeObject(w_obj)
+
+    def list_is_correct_type(self, w_list):
+        return w_list.strategy is self.space.fromcache(UnicodeListStrategy)
+
+    def sort(self, w_list, reverse):
+        l = self.unerase(w_list.lstorage)
+        sorter = UnicodeSort(l, len(l))
+        sorter.sort()
+        if reverse:
+            l.reverse()
+
+    def getitems_unicode(self, w_list):
+        return self.unerase(w_list.lstorage)
+
 # _______________________________________________________
 
 init_signature = Signature(['sequence'], None, None)
@@ -1387,6 +1440,7 @@
 IntBaseTimSort = make_timsort_class()
 FloatBaseTimSort = make_timsort_class()
 StringBaseTimSort = make_timsort_class()
+UnicodeBaseTimSort = make_timsort_class()
 
 class KeyContainer(baseobjspace.W_Root):
     def __init__(self, w_key, w_item):
@@ -1414,6 +1468,10 @@
     def lt(self, a, b):
         return a < b
 
+class UnicodeSort(UnicodeBaseTimSort):
+    def lt(self, a, b):
+        return a < b
+
 class CustomCompareSort(SimpleSort):
     def lt(self, a, b):
         space = self.space
diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py
--- a/pypy/objspace/std/objspace.py
+++ b/pypy/objspace/std/objspace.py
@@ -29,6 +29,7 @@
 from pypy.objspace.std.sliceobject import W_SliceObject
 from pypy.objspace.std.smallintobject import W_SmallIntObject
 from pypy.objspace.std.stringobject import W_StringObject
+from pypy.objspace.std.unicodeobject import W_UnicodeObject
 from pypy.objspace.std.tupleobject import W_AbstractTupleObject
 from pypy.objspace.std.typeobject import W_TypeObject
 
@@ -52,6 +53,8 @@
             self.StringObjectCls = W_RopeObject
         else:
             self.StringObjectCls = W_StringObject
+            
+        self.UnicodeObjectCls = W_UnicodeObject
 
         self._install_multimethods()
 
@@ -461,6 +464,21 @@
             return w_obj.getitems_str()
         return None
 
+    def listview_unicode(self, w_obj):
+        # note: uses exact type checking for objects with strategies,
+        # and isinstance() for others.  See test_listobject.test_uses_custom...
+        if type(w_obj) is W_ListObject:
+            return w_obj.getitems_unicode()
+        if type(w_obj) is W_DictMultiObject:
+            return w_obj.listview_unicode()
+        if type(w_obj) is W_SetObject or type(w_obj) is W_FrozensetObject:
+            return w_obj.listview_unicode()
+        if isinstance(w_obj, W_UnicodeObject):
+            return w_obj.listview_unicode()
+        if isinstance(w_obj, W_ListObject) and self._uses_list_iter(w_obj):
+            return w_obj.getitems_unicode()
+        return None
+
     def listview_int(self, w_obj):
         if type(w_obj) is W_ListObject:
             return w_obj.getitems_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,7 @@
 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.unicodeobject import W_UnicodeObject
 
 class W_BaseSetObject(W_Object):
     typedef = None
@@ -92,6 +93,10 @@
         """ If this is a string set return its contents as a list of uwnrapped strings. Otherwise return None. """
         return self.strategy.listview_str(self)
 
+    def listview_unicode(self):
+        """ If this is a unicode set return its contents as a list of uwnrapped unicodes. Otherwise return None. """
+        return self.strategy.listview_unicode(self)
+
     def listview_int(self):
         """ If this is an int set return its contents as a list of uwnrapped ints. Otherwise return None. """
         return self.strategy.listview_int(self)
@@ -201,6 +206,9 @@
     def listview_str(self, w_set):
         return None
 
+    def listview_unicode(self, w_set):
+        return None
+
     def listview_int(self, w_set):
         return None
 
@@ -303,6 +311,8 @@
             strategy = self.space.fromcache(IntegerSetStrategy)
         elif type(w_key) is W_StringObject:
             strategy = self.space.fromcache(StringSetStrategy)
+        elif type(w_key) is W_UnicodeObject:
+            strategy = self.space.fromcache(UnicodeSetStrategy)
         else:
             strategy = self.space.fromcache(ObjectSetStrategy)
         w_set.strategy = strategy
@@ -713,6 +723,41 @@
     def iter(self, w_set):
         return StringIteratorImplementation(self.space, self, w_set)
 
+
+class UnicodeSetStrategy(AbstractUnwrappedSetStrategy, SetStrategy):
+    erase, unerase = rerased.new_erasing_pair("unicode")
+    erase = staticmethod(erase)
+    unerase = staticmethod(unerase)
+
+    def get_empty_storage(self):
+        return self.erase({})
+
+    def get_empty_dict(self):
+        return {}
+
+    def listview_unicode(self, w_set):
+        return self.unerase(w_set.sstorage).keys()
+
+    def is_correct_type(self, w_key):
+        return type(w_key) is W_UnicodeObject
+
+    def may_contain_equal_elements(self, strategy):
+        if strategy is self.space.fromcache(IntegerSetStrategy):
+            return False
+        if strategy is self.space.fromcache(EmptySetStrategy):
+            return False
+        return True
+
+    def unwrap(self, w_item):
+        return self.space.unicode_w(w_item)
+
+    def wrap(self, item):
+        return self.space.wrap(item)
+
+    def iter(self, w_set):
+        return UnicodeIteratorImplementation(self.space, self, w_set)
+
+
 class IntegerSetStrategy(AbstractUnwrappedSetStrategy, SetStrategy):
     erase, unerase = rerased.new_erasing_pair("integer")
     erase = staticmethod(erase)
@@ -852,6 +897,18 @@
         else:
             return None
 
+class UnicodeIteratorImplementation(IteratorImplementation):
+    def __init__(self, space, strategy, w_set):
+        IteratorImplementation.__init__(self, space, strategy, w_set)
+        d = strategy.unerase(w_set.sstorage)
+        self.iterator = d.iterkeys()
+
+    def next_entry(self):
+        for key in self.iterator:
+            return self.space.wrap(key)
+        else:
+            return None
+
 class IntegerIteratorImplementation(IteratorImplementation):
     #XXX same implementation in dictmultiobject on dictstrategy-branch
     def __init__(self, space, strategy, w_set):
@@ -931,6 +988,13 @@
         w_set.sstorage = strategy.get_storage_from_unwrapped_list(stringlist)
         return
 
+    unicodelist = space.listview_unicode(w_iterable)
+    if unicodelist is not None:
+        strategy = space.fromcache(UnicodeSetStrategy)
+        w_set.strategy = strategy
+        w_set.sstorage = strategy.get_storage_from_unwrapped_list(unicodelist)
+        return
+
     intlist = space.listview_int(w_iterable)
     if intlist is not None:
         strategy = space.fromcache(IntegerSetStrategy)
diff --git a/pypy/objspace/std/test/test_dictmultiobject.py b/pypy/objspace/std/test/test_dictmultiobject.py
--- a/pypy/objspace/std/test/test_dictmultiobject.py
+++ b/pypy/objspace/std/test/test_dictmultiobject.py
@@ -144,33 +144,48 @@
 
     def test_listview_str_dict(self):
         w = self.space.wrap
-
         w_d = self.space.newdict()
         w_d.initialize_content([(w("a"), w(1)), (w("b"), w(2))])
+        assert self.space.listview_str(w_d) == ["a", "b"]
 
-        assert self.space.listview_str(w_d) == ["a", "b"]
+    def test_listview_unicode_dict(self):
+        w = self.space.wrap
+        w_d = self.space.newdict()
+        w_d.initialize_content([(w(u"a"), w(1)), (w(u"b"), w(2))])
+        assert self.space.listview_unicode(w_d) == [u"a", u"b"]
 
     def test_listview_int_dict(self):
         w = self.space.wrap
         w_d = self.space.newdict()
         w_d.initialize_content([(w(1), w("a")), (w(2), w("b"))])
-
         assert self.space.listview_int(w_d) == [1, 2]
 
-    def test_keys_on_string_int_dict(self):
+    def test_keys_on_string_unicode_int_dict(self, monkeypatch):
         w = self.space.wrap
+        
         w_d = self.space.newdict()
         w_d.initialize_content([(w(1), w("a")), (w(2), w("b"))])
-
         w_l = self.space.call_method(w_d, "keys")
         assert sorted(self.space.listview_int(w_l)) == [1,2]
-
+        
+        # make sure that .keys() calls newlist_str for string dicts
+        def not_allowed(*args):
+            assert False, 'should not be called'
+        monkeypatch.setattr(self.space, 'newlist', not_allowed)
+        #
         w_d = self.space.newdict()
         w_d.initialize_content([(w("a"), w(1)), (w("b"), w(6))])
-
         w_l = self.space.call_method(w_d, "keys")
         assert sorted(self.space.listview_str(w_l)) == ["a", "b"]
 
+        # XXX: it would be nice if the test passed without monkeypatch.undo(),
+        # but we need space.newlist_unicode for it
+        monkeypatch.undo() 
+        w_d = self.space.newdict()
+        w_d.initialize_content([(w(u"a"), w(1)), (w(u"b"), w(6))])
+        w_l = self.space.call_method(w_d, "keys")
+        assert sorted(self.space.listview_unicode(w_l)) == [u"a", u"b"]
+
 class AppTest_DictObject:
     def setup_class(cls):
         cls.w_on_pypy = cls.space.wrap("__pypy__" in sys.builtin_module_names)
@@ -799,6 +814,16 @@
         o.a = 1
         assert "StringDictStrategy" in self.get_strategy(d)
 
+    def test_empty_to_unicode(self):
+        d = {}
+        assert "EmptyDictStrategy" in self.get_strategy(d)
+        d[u"a"] = 1
+        assert "UnicodeDictStrategy" in self.get_strategy(d)
+        assert d[u"a"] == 1
+        assert d["a"] == 1
+        assert d.keys() == [u"a"]
+        assert type(d.keys()[0]) is unicode
+
     def test_empty_to_int(self):
         import sys
         d = {}
@@ -834,7 +859,7 @@
         raises(RuntimeError, list, it)
 
 
-class FakeString(str):
+class FakeWrapper(object):
     hash_count = 0
     def unwrap(self, space):
         self.unwrapped = True
@@ -844,6 +869,12 @@
         self.hash_count += 1
         return str.__hash__(self)
 
+class FakeString(FakeWrapper, str):
+    pass
+
+class FakeUnicode(FakeWrapper, unicode):
+    pass
+
 # the minimal 'space' needed to use a W_DictMultiObject
 class FakeSpace:
     hash_count = 0
@@ -916,6 +947,7 @@
     w_bool = bool
     w_float = float
     StringObjectCls = FakeString
+    UnicodeObjectCls = FakeUnicode
     w_dict = W_DictMultiObject
     iter = iter
     fixedview = list
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
@@ -1188,9 +1188,10 @@
         # strategies, to avoid surprizes depending on the strategy.
         class X: pass
         for base, arg in [
-                (list, []), (list, [5]), (list, ['x']), (list, [X]),
-                (set, []),  (set,  [5]), (set,  ['x']), (set, [X]),
+                (list, []), (list, [5]), (list, ['x']), (list, [X]), (list, [u'x']),
+                (set, []),  (set,  [5]), (set,  ['x']), (set, [X]), (set, [u'x']),
                 (dict, []), (dict, [(5,6)]), (dict, [('x',7)]), (dict, [(X,8)]),
+                (dict, [(u'x', 7)]),
                 ]:
             print base, arg
             class SubClass(base):
diff --git a/pypy/objspace/std/test/test_liststrategies.py b/pypy/objspace/std/test/test_liststrategies.py
--- a/pypy/objspace/std/test/test_liststrategies.py
+++ b/pypy/objspace/std/test/test_liststrategies.py
@@ -1,5 +1,5 @@
 import sys
-from pypy.objspace.std.listobject import W_ListObject, EmptyListStrategy, ObjectListStrategy, IntegerListStrategy, FloatListStrategy, StringListStrategy, RangeListStrategy, make_range_list
+from pypy.objspace.std.listobject import W_ListObject, EmptyListStrategy, ObjectListStrategy, IntegerListStrategy, FloatListStrategy, StringListStrategy, RangeListStrategy, make_range_list, UnicodeListStrategy
 from pypy.objspace.std import listobject
 from pypy.objspace.std.test.test_listobject import TestW_ListObject
 
@@ -8,34 +8,50 @@
 class TestW_ListStrategies(TestW_ListObject):
 
     def test_check_strategy(self):
-        assert isinstance(W_ListObject(self.space, []).strategy, EmptyListStrategy)
-        assert isinstance(W_ListObject(self.space, [self.space.wrap(1),self.space.wrap('a')]).strategy, ObjectListStrategy)
-        assert isinstance(W_ListObject(self.space, [self.space.wrap(1),self.space.wrap(2),self.space.wrap(3)]).strategy, IntegerListStrategy)
-        assert isinstance(W_ListObject(self.space, [self.space.wrap('a'), self.space.wrap('b')]).strategy, StringListStrategy)
-
+        space = self.space
+        w = space.wrap
+        assert isinstance(W_ListObject(space, []).strategy, EmptyListStrategy)
+        assert isinstance(W_ListObject(space, [w(1),w('a')]).strategy, ObjectListStrategy)
+        assert isinstance(W_ListObject(space, [w(1),w(2),w(3)]).strategy,
+                          IntegerListStrategy)
+        assert isinstance(W_ListObject(space, [w('a'), w('b')]).strategy,
+                          StringListStrategy)
+        assert isinstance(W_ListObject(space, [w(u'a'), w(u'b')]).strategy,
+                          UnicodeListStrategy)
+        assert isinstance(W_ListObject(space, [w(u'a'), w('b')]).strategy,
+                          ObjectListStrategy) # mixed unicode and bytes
+                                       
     def test_empty_to_any(self):
-        l = W_ListObject(self.space, [])
+        space = self.space
+        w = space.wrap
+        l = W_ListObject(space, [])
         assert isinstance(l.strategy, EmptyListStrategy)
-        l.append(self.space.wrap((1,3)))
+        l.append(w((1,3)))
         assert isinstance(l.strategy, ObjectListStrategy)
 
-        l = W_ListObject(self.space, [])
+        l = W_ListObject(space, [])
         assert isinstance(l.strategy, EmptyListStrategy)
-        l.append(self.space.wrap(1))
+        l.append(w(1))
         assert isinstance(l.strategy, IntegerListStrategy)
 
-        l = W_ListObject(self.space, [])
+        l = W_ListObject(space, [])
         assert isinstance(l.strategy, EmptyListStrategy)
-        l.append(self.space.wrap('a'))
+        l.append(w('a'))
         assert isinstance(l.strategy, StringListStrategy)
 
-        l = W_ListObject(self.space, [])
+        l = W_ListObject(space, [])
         assert isinstance(l.strategy, EmptyListStrategy)
-        l.append(self.space.wrap(1.2))
+        l.append(w(u'a'))
+        assert isinstance(l.strategy, UnicodeListStrategy)
+
+        l = W_ListObject(space, [])
+        assert isinstance(l.strategy, EmptyListStrategy)
+        l.append(w(1.2))
         assert isinstance(l.strategy, FloatListStrategy)
 
     def test_int_to_any(self):
-        l = W_ListObject(self.space, [self.space.wrap(1),self.space.wrap(2),self.space.wrap(3)])
+        l = W_ListObject(self.space,
+                         [self.space.wrap(1),self.space.wrap(2),self.space.wrap(3)])
         assert isinstance(l.strategy, IntegerListStrategy)
         l.append(self.space.wrap(4))
         assert isinstance(l.strategy, IntegerListStrategy)
@@ -43,15 +59,26 @@
         assert isinstance(l.strategy, ObjectListStrategy)
 
     def test_string_to_any(self):
-        l = W_ListObject(self.space, [self.space.wrap('a'),self.space.wrap('b'),self.space.wrap('c')])
+        l = W_ListObject(self.space,
+                         [self.space.wrap('a'),self.space.wrap('b'),self.space.wrap('c')])
         assert isinstance(l.strategy, StringListStrategy)
         l.append(self.space.wrap('d'))
         assert isinstance(l.strategy, StringListStrategy)
         l.append(self.space.wrap(3))
         assert isinstance(l.strategy, ObjectListStrategy)
 
+    def test_unicode_to_any(self):
+        space = self.space
+        l = W_ListObject(space, [space.wrap(u'a'), space.wrap(u'b'), space.wrap(u'c')])
+        assert isinstance(l.strategy, UnicodeListStrategy)
+        l.append(space.wrap(u'd'))
+        assert isinstance(l.strategy, UnicodeListStrategy)
+        l.append(space.wrap(3))
+        assert isinstance(l.strategy, ObjectListStrategy)
+
     def test_float_to_any(self):
-        l = W_ListObject(self.space, [self.space.wrap(1.1),self.space.wrap(2.2),self.space.wrap(3.3)])
+        l = W_ListObject(self.space,
+                         [self.space.wrap(1.1),self.space.wrap(2.2),self.space.wrap(3.3)])
         assert isinstance(l.strategy, FloatListStrategy)
         l.append(self.space.wrap(4.4))
         assert isinstance(l.strategy, FloatListStrategy)
@@ -59,66 +86,82 @@
         assert isinstance(l.strategy, ObjectListStrategy)
 
     def test_setitem(self):
+        space = self.space
+        w = space.wrap
         # This should work if test_listobject.py passes
-        l = W_ListObject(self.space, [self.space.wrap('a'),self.space.wrap('b'),self.space.wrap('c')])
-        assert self.space.eq_w(l.getitem(0), self.space.wrap('a'))
-        l.setitem(0, self.space.wrap('d'))
-        assert self.space.eq_w(l.getitem(0), self.space.wrap('d'))
+        l = W_ListObject(space, [w('a'),w('b'),w('c')])
+        assert space.eq_w(l.getitem(0), w('a'))
+        l.setitem(0, w('d'))
+        assert space.eq_w(l.getitem(0), w('d'))
 
         assert isinstance(l.strategy, StringListStrategy)
 
         # IntStrategy to ObjectStrategy
-        l = W_ListObject(self.space, [self.space.wrap(1),self.space.wrap(2),self.space.wrap(3)])
+        l = W_ListObject(space, [w(1),w(2),w(3)])
         assert isinstance(l.strategy, IntegerListStrategy)
-        l.setitem(0, self.space.wrap('d'))
+        l.setitem(0, w('d'))
         assert isinstance(l.strategy, ObjectListStrategy)
 
         # StringStrategy to ObjectStrategy
-        l = W_ListObject(self.space, [self.space.wrap('a'),self.space.wrap('b'),self.space.wrap('c')])
+        l = W_ListObject(space, [w('a'),w('b'),w('c')])
         assert isinstance(l.strategy, StringListStrategy)
-        l.setitem(0, self.space.wrap(2))
+        l.setitem(0, w(2))
+        assert isinstance(l.strategy, ObjectListStrategy)
+
+        # UnicodeStrategy to ObjectStrategy
+        l = W_ListObject(space, [w(u'a'),w(u'b'),w(u'c')])
+        assert isinstance(l.strategy, UnicodeListStrategy)
+        l.setitem(0, w(2))
         assert isinstance(l.strategy, ObjectListStrategy)
 
         # FloatStrategy to ObjectStrategy
-        l = W_ListObject(self.space, [self.space.wrap(1.2),self.space.wrap(2.3),self.space.wrap(3.4)])
+        l = W_ListObject(space, [w(1.2),w(2.3),w(3.4)])
         assert isinstance(l.strategy, FloatListStrategy)
-        l.setitem(0, self.space.wrap("a"))
+        l.setitem(0, w("a"))
         assert isinstance(l.strategy, ObjectListStrategy)
 
     def test_insert(self):
+        space = self.space
+        w = space.wrap
         # no change
-        l = W_ListObject(self.space, [self.space.wrap(1),self.space.wrap(2),self.space.wrap(3)])
+        l = W_ListObject(space, [w(1),w(2),w(3)])
         assert isinstance(l.strategy, IntegerListStrategy)
-        l.insert(3, self.space.wrap(4))
+        l.insert(3, w(4))
         assert isinstance(l.strategy, IntegerListStrategy)
 
         # StringStrategy
-        l = W_ListObject(self.space, [self.space.wrap('a'),self.space.wrap('b'),self.space.wrap('c')])
+        l = W_ListObject(space, [w('a'),w('b'),w('c')])
         assert isinstance(l.strategy, StringListStrategy)
-        l.insert(3, self.space.wrap(2))
+        l.insert(3, w(2))
+        assert isinstance(l.strategy, ObjectListStrategy)
+
+        # UnicodeStrategy
+        l = W_ListObject(space, [w(u'a'),w(u'b'),w(u'c')])
+        assert isinstance(l.strategy, UnicodeListStrategy)
+        l.insert(3, w(2))
         assert isinstance(l.strategy, ObjectListStrategy)
 
         # IntegerStrategy
-        l = W_ListObject(self.space, [self.space.wrap(1),self.space.wrap(2),self.space.wrap(3)])
+        l = W_ListObject(space, [w(1),w(2),w(3)])
         assert isinstance(l.strategy, IntegerListStrategy)
-        l.insert(3, self.space.wrap('d'))
+        l.insert(3, w('d'))
         assert isinstance(l.strategy, ObjectListStrategy)
 
         # FloatStrategy
-        l = W_ListObject(self.space, [self.space.wrap(1.1),self.space.wrap(2.2),self.space.wrap(3.3)])
+        l = W_ListObject(space, [w(1.1),w(2.2),w(3.3)])
         assert isinstance(l.strategy, FloatListStrategy)
-        l.insert(3, self.space.wrap('d'))
+        l.insert(3, w('d'))
         assert isinstance(l.strategy, ObjectListStrategy)
 
         # EmptyStrategy
-        l = W_ListObject(self.space, [])
+        l = W_ListObject(space, [])
         assert isinstance(l.strategy, EmptyListStrategy)
-        l.insert(0, self.space.wrap('a'))
+        l.insert(0, w('a'))
         assert isinstance(l.strategy, StringListStrategy)
 
-        l = W_ListObject(self.space, [])
+        l = W_ListObject(space, [])
         assert isinstance(l.strategy, EmptyListStrategy)
-        l.insert(0, self.space.wrap(2))
+        l.insert(0, w(2))
         assert isinstance(l.strategy, IntegerListStrategy)
 
     def test_list_empty_after_delete(self):
@@ -140,47 +183,57 @@
         assert isinstance(l.strategy, EmptyListStrategy)
 
     def test_setslice(self):
-        l = W_ListObject(self.space, [])
+        space = self.space
+        w = space.wrap
+        
+        l = W_ListObject(space, [])
         assert isinstance(l.strategy, EmptyListStrategy)
-        l.setslice(0, 1, 2, W_ListObject(self.space, [self.space.wrap(1), self.space.wrap(2), self.space.wrap(3)]))
+        l.setslice(0, 1, 2, W_ListObject(space, [w(1), w(2), w(3)]))
         assert isinstance(l.strategy, IntegerListStrategy)
 
         # IntegerStrategy to IntegerStrategy
-        l = W_ListObject(self.space, [self.space.wrap(1), self.space.wrap(2), self.space.wrap(3)])
+        l = W_ListObject(space, [w(1), w(2), w(3)])
         assert isinstance(l.strategy, IntegerListStrategy)
-        l.setslice(0, 1, 2, W_ListObject(self.space, [self.space.wrap(4), self.space.wrap(5), self.space.wrap(6)]))
+        l.setslice(0, 1, 2, W_ListObject(space, [w(4), w(5), w(6)]))
         assert isinstance(l.strategy, IntegerListStrategy)
 
         # ObjectStrategy to ObjectStrategy
-        l = W_ListObject(self.space, [self.space.wrap(1), self.space.wrap('b'), self.space.wrap(3)])
+        l = W_ListObject(space, [w(1), w('b'), w(3)])
         assert isinstance(l.strategy, ObjectListStrategy)
-        l.setslice(0, 1, 2, W_ListObject(self.space, [self.space.wrap(1), self.space.wrap(2), self.space.wrap(3)]))
+        l.setslice(0, 1, 2, W_ListObject(space, [w(1), w(2), w(3)]))
         assert isinstance(l.strategy, ObjectListStrategy)
 
         # IntegerStrategy to ObjectStrategy
-        l = W_ListObject(self.space, [self.space.wrap(1), self.space.wrap(2), self.space.wrap(3)])
+        l = W_ListObject(space, [w(1), w(2), w(3)])
         assert isinstance(l.strategy, IntegerListStrategy)
-        l.setslice(0, 1, 2, W_ListObject(self.space, [self.space.wrap('a'), self.space.wrap('b'), self.space.wrap('c')]))
+        l.setslice(0, 1, 2, W_ListObject(space, [w('a'), w('b'), w('c')]))
         assert isinstance(l.strategy, ObjectListStrategy)
 
         # StringStrategy to ObjectStrategy
-        l = W_ListObject(self.space, [self.space.wrap('a'), self.space.wrap('b'), self.space.wrap('c')])
+        l = W_ListObject(space, [w('a'), w('b'), w('c')])
         assert isinstance(l.strategy, StringListStrategy)
-        l.setslice(0, 1, 2, W_ListObject(self.space, [self.space.wrap(1), self.space.wrap(2), self.space.wrap(3)]))
+        l.setslice(0, 1, 2, W_ListObject(space, [w(1), w(2), w(3)]))
+        assert isinstance(l.strategy, ObjectListStrategy)
+
+        # UnicodeStrategy to ObjectStrategy
+        l = W_ListObject(space, [w(u'a'), w(u'b'), w(u'c')])
+        assert isinstance(l.strategy, UnicodeListStrategy)
+        l.setslice(0, 1, 2, W_ListObject(space, [w(1), w(2), w(3)]))
         assert isinstance(l.strategy, ObjectListStrategy)
 
         # FloatStrategy to ObjectStrategy
-        l = W_ListObject(self.space, [self.space.wrap(1.1), self.space.wrap(2.2), self.space.wrap(3.3)])
+        l = W_ListObject(space, [w(1.1), w(2.2), w(3.3)])
         assert isinstance(l.strategy, FloatListStrategy)
-        l.setslice(0, 1, 2, W_ListObject(self.space, [self.space.wrap('a'), self.space.wrap(2), self.space.wrap(3)]))
+        l.setslice(0, 1, 2, W_ListObject(space, [w('a'), w(2), w(3)]))
         assert isinstance(l.strategy, ObjectListStrategy)
 
     def test_setslice_List(self):
+        space = self.space
 
         def wrapitems(items):
             items_w = []
             for i in items:
-                items_w.append(self.space.wrap(i))
+                items_w.append(space.wrap(i))
             return items_w
 
         def keep_other_strategy(w_list, start, step, length, w_other):
@@ -188,103 +241,124 @@
             w_list.setslice(start, step, length, w_other)
             assert w_other.strategy is other_strategy
 
-        l = W_ListObject(self.space, wrapitems([1,2,3,4,5]))
-        other = W_ListObject(self.space, wrapitems(["a", "b", "c"]))
+        l = W_ListObject(space, wrapitems([1,2,3,4,5]))
+        other = W_ListObject(space, wrapitems(["a", "b", "c"]))
         keep_other_strategy(l, 0, 2, other.length(), other)
-        assert l.strategy is self.space.fromcache(ObjectListStrategy)
+        assert l.strategy is space.fromcache(ObjectListStrategy)
 
-        l = W_ListObject(self.space, wrapitems([1,2,3,4,5]))
-        other = W_ListObject(self.space, wrapitems([6, 6, 6]))
+        l = W_ListObject(space, wrapitems([1,2,3,4,5]))
+        other = W_ListObject(space, wrapitems([6, 6, 6]))
         keep_other_strategy(l, 0, 2, other.length(), other)
-        assert l.strategy is self.space.fromcache(IntegerListStrategy)
+        assert l.strategy is space.fromcache(IntegerListStrategy)
 
-        l = W_ListObject(self.space, wrapitems(["a","b","c","d","e"]))
-        other = W_ListObject(self.space, wrapitems(["a", "b", "c"]))
+        l = W_ListObject(space, wrapitems(["a","b","c","d","e"]))
+        other = W_ListObject(space, wrapitems(["a", "b", "c"]))
         keep_other_strategy(l, 0, 2, other.length(), other)
-        assert l.strategy is self.space.fromcache(StringListStrategy)
+        assert l.strategy is space.fromcache(StringListStrategy)
 
-        l = W_ListObject(self.space, wrapitems([1.1, 2.2, 3.3, 4.4, 5.5]))
-        other = W_ListObject(self.space, [])
+        l = W_ListObject(space, wrapitems([u"a",u"b",u"c",u"d",u"e"]))
+        other = W_ListObject(space, wrapitems([u"a", u"b", u"c"]))
+        keep_other_strategy(l, 0, 2, other.length(), other)
+        assert l.strategy is space.fromcache(UnicodeListStrategy)
+
+        l = W_ListObject(space, wrapitems([1.1, 2.2, 3.3, 4.4, 5.5]))
+        other = W_ListObject(space, [])
         keep_other_strategy(l, 0, 1, l.length(), other)
-        assert l.strategy is self.space.fromcache(FloatListStrategy)
+        assert l.strategy is space.fromcache(FloatListStrategy)
 
-        l = W_ListObject(self.space, wrapitems(["a",3,"c",4,"e"]))
-        other = W_ListObject(self.space, wrapitems(["a", "b", "c"]))
+        l = W_ListObject(space, wrapitems(["a",3,"c",4,"e"]))
+        other = W_ListObject(space, wrapitems(["a", "b", "c"]))
         keep_other_strategy(l, 0, 2, other.length(), other)
-        assert l.strategy is self.space.fromcache(ObjectListStrategy)
+        assert l.strategy is space.fromcache(ObjectListStrategy)
 
-        l = W_ListObject(self.space, wrapitems(["a",3,"c",4,"e"]))
-        other = W_ListObject(self.space, [])
+        l = W_ListObject(space, wrapitems(["a",3,"c",4,"e"]))
+        other = W_ListObject(space, [])
         keep_other_strategy(l, 0, 1, l.length(), other)
-        assert l.strategy is self.space.fromcache(ObjectListStrategy)
+        assert l.strategy is space.fromcache(ObjectListStrategy)
 
     def test_empty_setslice_with_objectlist(self):
-        l = W_ListObject(self.space, [])
-        o = W_ListObject(self.space, [self.space.wrap(1), self.space.wrap("2"), self.space.wrap(3)])
+        space = self.space
+        w = space.wrap
+        
+        l = W_ListObject(space, [])
+        o = W_ListObject(space, [space.wrap(1), space.wrap("2"), space.wrap(3)])
         l.setslice(0, 1, o.length(), o)
         assert l.getitems() == o.getitems()
-        l.append(self.space.wrap(17))
+        l.append(space.wrap(17))
         assert l.getitems() != o.getitems()
 
     def test_extend(self):
-        l = W_ListObject(self.space, [])
+        space = self.space
+        w = space.wrap
+
+        l = W_ListObject(space, [])
         assert isinstance(l.strategy, EmptyListStrategy)
-        l.extend(W_ListObject(self.space, [self.space.wrap(1), self.space.wrap(2), self.space.wrap(3)]))
+        l.extend(W_ListObject(space, [w(1), w(2), w(3)]))
         assert isinstance(l.strategy, IntegerListStrategy)
 
-        l = W_ListObject(self.space, [self.space.wrap(1), self.space.wrap(2), self.space.wrap(3)])
+        l = W_ListObject(space, [w(1), w(2), w(3)])
         assert isinstance(l.strategy, IntegerListStrategy)
-        l.extend(W_ListObject(self.space, [self.space.wrap('a'), self.space.wrap('b'), self.space.wrap('c')]))
+        l.extend(W_ListObject(space, [w('a'), w('b'), w('c')]))
         assert isinstance(l.strategy, ObjectListStrategy)
 
-        l = W_ListObject(self.space, [self.space.wrap(1), self.space.wrap(2), self.space.wrap(3)])
+        l = W_ListObject(space, [w(1), w(2), w(3)])
         assert isinstance(l.strategy, IntegerListStrategy)
-        l.extend(W_ListObject(self.space, [self.space.wrap(4), self.space.wrap(5), self.space.wrap(6)]))
+        l.extend(W_ListObject(space, [w(4), w(5), w(6)]))
         assert isinstance(l.strategy, IntegerListStrategy)
 
-        l = W_ListObject(self.space, [self.space.wrap(1.1), self.space.wrap(2.2), self.space.wrap(3.3)])
+        l = W_ListObject(space, [w(1.1), w(2.2), w(3.3)])
         assert isinstance(l.strategy, FloatListStrategy)
-        l.extend(W_ListObject(self.space, [self.space.wrap(4), self.space.wrap(5), self.space.wrap(6)]))
+        l.extend(W_ListObject(space, [w(4), w(5), w(6)]))
         assert isinstance(l.strategy, ObjectListStrategy)
 
     def test_empty_extend_with_any(self):
-        empty = W_ListObject(self.space, [])
+        space = self.space
+        w = space.wrap
+
+        empty = W_ListObject(space, [])
         assert isinstance(empty.strategy, EmptyListStrategy)
-        empty.extend(W_ListObject(self.space, [self.space.wrap(1), self.space.wrap(2), self.space.wrap(3)]))
+        empty.extend(W_ListObject(space, [w(1), w(2), w(3)]))
         assert isinstance(empty.strategy, IntegerListStrategy)
 
-        empty = W_ListObject(self.space, [])
+        empty = W_ListObject(space, [])
         assert isinstance(empty.strategy, EmptyListStrategy)
-        empty.extend(W_ListObject(self.space, [self.space.wrap("a"), self.space.wrap("b"), self.space.wrap("c")]))
+        empty.extend(W_ListObject(space, [w("a"), w("b"), w("c")]))
         assert isinstance(empty.strategy, StringListStrategy)
 
-        empty = W_ListObject(self.space, [])
+        empty = W_ListObject(space, [])
         assert isinstance(empty.strategy, EmptyListStrategy)
-        r = make_range_list(self.space, 1,3,7)
+        empty.extend(W_ListObject(space, [w(u"a"), w(u"b"), w(u"c")]))
+        assert isinstance(empty.strategy, UnicodeListStrategy)
+
+        empty = W_ListObject(space, [])
+        assert isinstance(empty.strategy, EmptyListStrategy)
+        r = make_range_list(space, 1,3,7)
         empty.extend(r)
         assert isinstance(empty.strategy, RangeListStrategy)
         print empty.getitem(6)
-        assert self.space.is_true(self.space.eq(empty.getitem(1), self.space.wrap(4)))
+        assert space.is_true(space.eq(empty.getitem(1), w(4)))
 
-        empty = W_ListObject(self.space, [])
+        empty = W_ListObject(space, [])
         assert isinstance(empty.strategy, EmptyListStrategy)
-        empty.extend(W_ListObject(self.space, [self.space.wrap(1), self.space.wrap(2), self.space.wrap(3)]))
+        empty.extend(W_ListObject(space, [w(1), w(2), w(3)]))
         assert isinstance(empty.strategy, IntegerListStrategy)
 
-        empty = W_ListObject(self.space, [])
+        empty = W_ListObject(space, [])
         assert isinstance(empty.strategy, EmptyListStrategy)
-        empty.extend(W_ListObject(self.space, [self.space.wrap(1.1), self.space.wrap(2.2), self.space.wrap(3.3)]))
+        empty.extend(W_ListObject(space, [w(1.1), w(2.2), w(3.3)]))
         assert isinstance(empty.strategy, FloatListStrategy)
 
-        empty = W_ListObject(self.space, [])
+        empty = W_ListObject(space, [])
         assert isinstance(empty.strategy, EmptyListStrategy)
-        empty.extend(W_ListObject(self.space, []))
+        empty.extend(W_ListObject(space, []))
         assert isinstance(empty.strategy, EmptyListStrategy)
 
     def test_extend_other_with_empty(self):
-        l = W_ListObject(self.space, [self.space.wrap(1), self.space.wrap(2), self.space.wrap(3)])
+        space = self.space
+        w = space.wrap
+        l = W_ListObject(space, [w(1), w(2), w(3)])
         assert isinstance(l.strategy, IntegerListStrategy)
-        l.extend(W_ListObject(self.space, []))
+        l.extend(W_ListObject(space, []))
         assert isinstance(l.strategy, IntegerListStrategy)
 
     def test_rangelist(self):
@@ -431,7 +505,7 @@
         l1 = W_ListObject(self.space, [self.space.wrap("eins"), self.space.wrap("zwei")])
         assert isinstance(l1.strategy, StringListStrategy)
         l2 = W_ListObject(self.space, [self.space.wrap(u"eins"), self.space.wrap(u"zwei")])
-        assert isinstance(l2.strategy, ObjectListStrategy)
+        assert isinstance(l2.strategy, UnicodeListStrategy)
         l3 = W_ListObject(self.space, [self.space.wrap("eins"), self.space.wrap(u"zwei")])
         assert isinstance(l3.strategy, ObjectListStrategy)
 
@@ -441,11 +515,22 @@
         w_l = self.space.newlist([self.space.wrap('a'), self.space.wrap('b')])
         assert space.listview_str(w_l) == ["a", "b"]
 
+    def test_listview_unicode(self):
+        space = self.space
+        assert space.listview_unicode(space.wrap(1)) == None
+        w_l = self.space.newlist([self.space.wrap(u'a'), self.space.wrap(u'b')])
+        assert space.listview_unicode(w_l) == [u"a", u"b"]
+
     def test_string_join_uses_listview_str(self):
         space = self.space
         w_l = self.space.newlist([self.space.wrap('a'), self.space.wrap('b')])
         w_l.getitems = None
         assert space.str_w(space.call_method(space.wrap("c"), "join", w_l)) == "acb"
+        #
+        # the same for unicode
+        w_l = self.space.newlist([self.space.wrap(u'a'), self.space.wrap(u'b')])
+        w_l.getitems = None
+        assert space.unicode_w(space.call_method(space.wrap(u"c"), "join", w_l)) == u"acb"
 
     def test_string_join_returns_same_instance(self):
         space = self.space
@@ -453,6 +538,12 @@
         w_l = self.space.newlist([w_text])
         w_l.getitems = None
         assert space.is_w(space.call_method(space.wrap(" -- "), "join", w_l), w_text)
+        #
+        # the same for unicode
+        w_text = space.wrap(u"text")
+        w_l = self.space.newlist([w_text])
+        w_l.getitems = None
+        assert space.is_w(space.call_method(space.wrap(u" -- "), "join", w_l), w_text)
 
     def test_newlist_str(self):
         space = self.space
@@ -513,6 +604,11 @@
         w_l = W_ListObject(space, [space.wrap("a"), space.wrap("b")])
         assert self.space.listview_str(w_l) == ["a", "b"]
 
+    def test_listview_unicode_list(self):
+        space = self.space
+        w_l = W_ListObject(space, [space.wrap(u"a"), space.wrap(u"b")])
+        assert self.space.listview_unicode(w_l) == [u"a", u"b"]
+
     def test_listview_int_list(self):
         space = self.space
         w_l = W_ListObject(space, [space.wrap(1), space.wrap(2), space.wrap(3)])
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
@@ -1,5 +1,10 @@
 from pypy.objspace.std.setobject import W_SetObject
-from pypy.objspace.std.setobject import IntegerSetStrategy, ObjectSetStrategy, EmptySetStrategy
+from pypy.objspace.std.setobject import (IntegerSetStrategy, ObjectSetStrategy,
+                                         EmptySetStrategy, StringSetStrategy,
+                                         UnicodeSetStrategy,
+                                         IntegerIteratorImplementation,
+                                         StringIteratorImplementation,
+                                         UnicodeIteratorImplementation)
 from pypy.objspace.std.listobject import W_ListObject
 
 class TestW_SetStrategies:
@@ -20,6 +25,12 @@
         s = W_SetObject(self.space, self.wrapped([]))
         assert s.strategy is self.space.fromcache(EmptySetStrategy)
 
+        s = W_SetObject(self.space, self.wrapped(["a", "b"]))
+        assert s.strategy is self.space.fromcache(StringSetStrategy)
+
+        s = W_SetObject(self.space, self.wrapped([u"a", u"b"]))
+        assert s.strategy is self.space.fromcache(UnicodeSetStrategy)
+
     def test_switch_to_object(self):
         s = W_SetObject(self.space, self.wrapped([1,2,3,4,5]))
         s.add(self.space.wrap("six"))
@@ -30,6 +41,11 @@
         s1.update(s2)
         assert s1.strategy is self.space.fromcache(ObjectSetStrategy)
 
+    def test_switch_to_unicode(self):
+        s = W_SetObject(self.space, self.wrapped([]))
+        s.add(self.space.wrap(u"six"))
+        assert s.strategy is self.space.fromcache(UnicodeSetStrategy)
+
     def test_symmetric_difference(self):
         s1 = W_SetObject(self.space, self.wrapped([1,2,3,4,5]))
         s2 = W_SetObject(self.space, self.wrapped(["six", "seven"]))
@@ -105,3 +121,34 @@
 
         assert s1.has_key(self.space.wrap(FakeInt(2)))
         assert s1.strategy is self.space.fromcache(ObjectSetStrategy)
+
+    def test_iter(self):
+        space = self.space
+        s = W_SetObject(space, self.wrapped([1,2]))
+        it = s.iter()
+        assert isinstance(it, IntegerIteratorImplementation)
+        assert space.unwrap(it.next()) == 1
+        assert space.unwrap(it.next()) == 2
+        #
+        s = W_SetObject(space, self.wrapped(["a", "b"]))
+        it = s.iter()
+        assert isinstance(it, StringIteratorImplementation)
+        assert space.unwrap(it.next()) == "a"
+        assert space.unwrap(it.next()) == "b"
+        #
+        s = W_SetObject(space, self.wrapped([u"a", u"b"]))
+        it = s.iter()
+        assert isinstance(it, UnicodeIteratorImplementation)
+        assert space.unwrap(it.next()) == u"a"
+        assert space.unwrap(it.next()) == u"b"
+
+    def test_listview(self):
+        space = self.space
+        s = W_SetObject(space, self.wrapped([1,2]))
+        assert sorted(space.listview_int(s)) == [1, 2]
+        #
+        s = W_SetObject(space, self.wrapped(["a", "b"]))
+        assert sorted(space.listview_str(s)) == ["a", "b"]
+        #
+        s = W_SetObject(space, self.wrapped([u"a", u"b"]))
+        assert sorted(space.listview_unicode(s)) == [u"a", u"b"]
diff --git a/pypy/objspace/std/test/test_unicodeobject.py b/pypy/objspace/std/test/test_unicodeobject.py
--- a/pypy/objspace/std/test/test_unicodeobject.py
+++ b/pypy/objspace/std/test/test_unicodeobject.py
@@ -23,6 +23,10 @@
         print self.space.config.objspace.std.withrope
         assert len(warnings) == 2
 
+    def test_listview_unicode(self):
+        w_str = self.space.wrap(u'abcd')
+        assert self.space.listview_unicode(w_str) == list(u"abcd")
+
 
 class AppTestUnicodeStringStdOnly:
     def test_compares(self):
diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py
--- a/pypy/objspace/std/unicodeobject.py
+++ b/pypy/objspace/std/unicodeobject.py
@@ -66,6 +66,15 @@
     def unicode_w(self, space):
         return self._value
 
+    def listview_unicode(w_self):
+        return _create_list_from_unicode(w_self._value)
+
+def _create_list_from_unicode(value):
+    # need this helper function to allow the jit to look inside and inline
+    # listview_unicode
+    return [s for s in value]
+
+
 W_UnicodeObject.EMPTY = W_UnicodeObject(u'')
 
 registerimplementation(W_UnicodeObject)
@@ -202,6 +211,11 @@
     return space.newbool(container.find(item) != -1)
 
 def unicode_join__Unicode_ANY(space, w_self, w_list):
+    l = space.listview_unicode(w_list)
+    if l is not None:
+        if len(l) == 1:
+            return space.wrap(l[0])
+        return space.wrap(w_self._value.join(l))
     list_w = space.listview(w_list)
     size = len(list_w)
 


More information about the pypy-commit mailing list