Author: Vincent Legoll <vincent.leg...@idgrilles.fr>
Branch: repeatlist_strategy
Changeset: r81677:856e309b020f
Date: 2016-01-11 21:55 +0100
http://bitbucket.org/pypy/pypy/changeset/856e309b020f/

Log:    Initial commit
        - some tests still fail because mul() is not allowed to call clone()

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
@@ -35,11 +35,17 @@
 from pypy.objspace.std.unicodeobject import W_UnicodeObject
 from pypy.objspace.std.util import get_positive_index, negate
 
-__all__ = ['W_ListObject', 'make_range_list', 'make_empty_list_with_size']
+__all__ = ['W_ListObject', "make_repeat_list",  'make_range_list', 
'make_empty_list_with_size']
 
 
 UNROLL_CUTOFF = 5
 
+def make_repeat_list(space, w_item, length):
+    if length <= 0:
+        return make_empty_list(space)
+    strategy = space.fromcache(RepeatListStrategy)
+    storage = strategy.erase((w_item, length))
+    return W_ListObject.from_storage_and_strategy(space, storage, strategy)
 
 def make_range_list(space, start, step, length):
     if length <= 0:
@@ -961,7 +967,7 @@
 
     def setslice(self, w_list, start, step, slicelength, w_other):
         strategy = w_other.strategy
-        storage = strategy.getstorage_copy(w_other)
+        storage = strategy.getstorage_copy(w_other) # XXX Why not 
strategy.copy_into(w_other, w_list) ?
         w_list.strategy = strategy
         w_list.lstorage = storage
 
@@ -1031,6 +1037,224 @@
         self.sizehint = hint
 
 
+class RepeatListStrategy(ListStrategy):
+    """RepeatListStrategy is used when a list is created using the 
multiplication
+       operator on iterables. The storage is a two elements tuple, with the
+       repeated item, and a positive integer storing the length."""
+
+    erase, unerase = rerased.new_erasing_pair("repeat")
+    erase = staticmethod(erase)
+    unerase = staticmethod(unerase)
+
+    def unwrap(self, w_obj):
+        return w_obj
+
+    def wrap(self, item):
+        return item
+
+    def clone(self, w_list):
+        storage = w_list.lstorage  # lstorage is tuple, no need to clone
+        w_clone = W_ListObject.from_storage_and_strategy(self.space, storage,
+                                                         self)
+        return w_clone
+
+    def copy_into(self, w_list, w_other):
+        w_other.strategy = self
+        w_other.lstorage = w_list.lstorage
+
+    def _resize_hint(self, w_list, hint):
+        raise NotImplementedError
+
+    def find(self, w_list, w_item, start, stop):
+        w_l_item, length = self.unerase(w_list.lstorage)
+        if length > 0 and start < length and self.space.eq_w(w_l_item, w_item):
+            return 0
+        raise ValueError
+
+    def switch_to_item_strategy(self, w_list, w_item=None):
+        w_l_item, length = self.unerase(w_list.lstorage)
+        w_item_type = type(w_l_item)
+        if w_item is not None and type(w_item) is w_item_type:
+            if w_item_type is W_IntObject:
+                strategy = self.space.fromcache(IntegerListStrategy)
+                item_w = strategy.unwrap(w_l_item)
+                lstorage = [item_w] * length
+                w_list.lstorage = strategy.erase(lstorage)
+                w_list.strategy = strategy
+                return
+            elif w_item_type is W_BytesObject:
+                strategy = self.space.fromcache(BytesListStrategy)
+                item_w = strategy.unwrap(w_l_item)
+                lstorage = [item_w] * length
+                w_list.lstorage = strategy.erase(lstorage)
+                w_list.strategy = strategy
+                return
+            elif w_item_type is W_UnicodeObject:
+                strategy = self.space.fromcache(UnicodeListStrategy)
+                item_w = strategy.unwrap(w_l_item)
+                lstorage = [item_w] * length
+                w_list.lstorage = strategy.erase(lstorage)
+                w_list.strategy = strategy
+                return
+            elif w_item_type is W_FloatObject:
+                strategy = self.space.fromcache(FloatListStrategy)
+                item_w = strategy.unwrap(w_l_item)
+                lstorage = [item_w] * length
+                w_list.lstorage = strategy.erase(lstorage) # XXX: use 
init_from_list_w too ? or define init_from_list_unw() ?
+                w_list.strategy = strategy
+                return
+        # Fall back to ObjectListStrategy
+        strategy = self.space.fromcache(ObjectListStrategy)
+        w_list.strategy = strategy
+        items = [w_l_item] * length
+        strategy.init_from_list_w(w_list, items)
+
+    def append(self, w_list, w_item):
+        w_l_item, length = self.unerase(w_list.lstorage)
+        if type(w_item) is type(w_l_item):
+            if self.space.eq_w(w_item, w_l_item):
+                w_list.lstorage = self.erase((w_l_item, length + 1))
+                return
+        self.switch_to_item_strategy(w_list, w_item)
+        w_list.strategy.append(w_list, w_item)
+
+    def length(self, w_list):
+        return self.unerase(w_list.lstorage)[1]
+
+    def getslice(self, w_list, start, stop, step, another_length):
+        w_l_item, length = self.unerase(w_list.lstorage)
+        if step > 0 and start < stop:
+            new_length = (stop - start)
+            if step != 1:
+                pad = 0
+                if new_length % step:
+                    pad = 1
+                new_length = pad + new_length / step
+        elif step < 0 and stop < start:
+            new_length = (start - stop)
+            if step != -1:
+                pad = 0
+                if new_length % -step:
+                    pad = 1
+                new_length = pad + new_length / -step
+        elif step == 0:
+            raise NotImplementedError
+        else:
+            return make_empty_list(self.space)
+        storage = self.erase((w_l_item, new_length))
+        return W_ListObject.from_storage_and_strategy(
+                self.space, storage, self)
+
+    def getitem(self, w_list, index):
+        if index < self.length(w_list):
+            return self.unerase(w_list.lstorage)[0]
+        raise IndexError
+
+    def getstorage_copy(self, w_list):
+        # tuple is immutable
+        return w_list.lstorage
+
+    def getitems(self, w_list):
+        return self.getitems_copy(w_list)
+
+    @jit.look_inside_iff(lambda self, w_list:
+            jit.loop_unrolling_heuristic(w_list, w_list.length(),
+                                         UNROLL_CUTOFF))
+    def getitems_copy(self, w_list):
+        w_l_item, length = self.unerase(w_list.lstorage)
+        return [w_l_item] * length
+
+    @jit.unroll_safe
+    def getitems_unroll(self, w_list):
+        w_l_item, length = self.unerase(w_list.lstorage)
+        return [w_l_item] * length
+
+    @jit.look_inside_iff(lambda self, w_list:
+            jit.loop_unrolling_heuristic(w_list, w_list.length(),
+                                         UNROLL_CUTOFF))
+    def getitems_fixedsize(self, w_list):
+        return self.getitems_unroll(w_list)
+
+    def pop_end(self, w_list):
+        w_l_item, length = self.unerase(w_list.lstorage)
+        if length != 0:
+            w_list.lstorage = self.erase((w_l_item, length - 1))
+            return w_l_item
+        raise IndexError
+
+    def pop(self, w_list, index):
+        w_l_item, length = self.unerase(w_list.lstorage)
+        if -length <= index < length:
+            w_list.lstorage = self.erase((w_l_item, length - 1))
+            return w_l_item
+        raise IndexError
+
+    def _extend_from_list(self, w_list, w_other):
+        if w_other.length() == 0:
+            return
+        if w_other.strategy is self.space.fromcache(RepeatListStrategy):
+            w_l_item, l_length = self.unerase(w_list.lstorage)
+            w_o_item, o_length = self.unerase(w_other.lstorage)
+            if self.space.eq_w(w_l_item, w_o_item):
+                w_list.lstorage = self.erase((w_l_item, l_length + o_length))
+                return
+        self.switch_to_item_strategy(w_list)
+        w_list.extend(w_other)
+
+    def inplace_mul(self, w_list, times):
+        if times > 0:
+            w_l_item, length = self.unerase(w_list.lstorage)
+            w_list.lstorage = self.erase((w_l_item, length * times))
+        else:
+            strategy = self.space.fromcache(EmptyListStrategy)
+            w_list.strategy = strategy
+            w_list.lstorage = strategy.erase(None)
+
+    def reverse(self, w_list):
+        return
+
+    def sort(self, w_list, reverse):
+        return
+
+    def insert(self, w_list, index, w_item):
+        w_l_item, length = self.unerase(w_list.lstorage)
+        if index >= length:
+            raise IndexError
+        if self.space.eq_w(w_item, w_l_item):
+            w_list.lstorage = self.erase((w_l_item, length + 1))
+            return
+        self.switch_to_item_strategy(w_list, w_item)
+        w_list.insert(index, w_item)
+
+    def setitem(self, w_list, index, w_item):
+        w_l_item, length = self.unerase(w_list.lstorage)
+        if index >= length:
+            raise IndexError
+        if self.space.eq_w(w_item, w_l_item):
+            return
+        self.switch_to_item_strategy(w_list, w_item)
+        w_list.setitem(index, w_item)
+
+    def setslice(self, w_list, start, step, slicelength, w_other):
+        assert slicelength >= 0
+        if w_other.length() == 0:
+            self.deleteslice(w_list, start, step, slicelength)
+            return
+        if w_other.strategy is self.space.fromcache(RepeatListStrategy):
+            w_l_item, l_length = self.unerase(w_list.lstorage)
+            w_o_item, o_length = self.unerase(w_other.lstorage)
+            if self.space.eq_w(w_l_item, w_o_item):
+                w_list.lstorage = self.erase((w_l_item, l_length + o_length - 
slicelength))
+                return
+        self.switch_to_item_strategy(w_list)
+        w_list.setslice(start, step, slicelength, w_other)
+
+    def deleteslice(self, w_list, start, step, slicelength):
+        if slicelength == 0:
+            return
+        w_l_item, length = self.unerase(w_list.lstorage)
+        w_list.lstorage = self.erase((w_l_item, length - slicelength))
+
 class BaseRangeListStrategy(ListStrategy):
     def switch_to_integer_strategy(self, w_list):
         items = self._getitems_range(w_list, False)
@@ -1570,11 +1794,80 @@
         return w_item
 
     def mul(self, w_list, times):
+        assert w_list.strategy is not self.space.fromcache(RepeatListStrategy)
+        if times <= 0:
+            return make_empty_list(self.space)
+        if w_list.length() == 1:
+            w_l_ret = w_list.clone()
+            if self.switch_to_repeat_strategy_inplace(w_l_ret, times):
+                return w_l_ret
         l = self.unerase(w_list.lstorage)
         return W_ListObject.from_storage_and_strategy(
             self.space, self.erase(l * times), self)
 
+    def switch_to_repeat_strategy_inplace(self, w_list, times):
+        if w_list.strategy is self.space.fromcache(ObjectListStrategy):
+            # Already wrapped
+            w_item = w_list.getitem(0)
+            strategy = self.space.fromcache(RepeatListStrategy)
+            w_list.strategy = strategy
+            w_list.lstorage = strategy.erase((w_item, times))
+            return True
+        if w_list.strategy is self.space.fromcache(IntegerListStrategy):
+            w_item = w_list.getitem(0)
+            assert isinstance(w_item, W_IntObject)
+            strategy = self.space.fromcache(RepeatListStrategy)
+            w_list.strategy = strategy
+            w_list.lstorage = strategy.erase((w_item, times))
+            return True
+        if w_list.strategy is self.space.fromcache(FloatListStrategy):
+            w_item = w_list.getitem(0)
+            assert isinstance(w_item, W_FloatObject)
+            strategy = self.space.fromcache(RepeatListStrategy)
+            w_list.strategy = strategy
+            w_list.lstorage = strategy.erase((w_item, times))
+            return True
+        if w_list.strategy is self.space.fromcache(IntOrFloatListStrategy):
+            w_item = w_list.getitem(0)
+            assert isinstance(w_item, W_FloatObject) or isinstance(w_item, 
W_IntObject)
+            strategy = self.space.fromcache(RepeatListStrategy)
+            w_list.strategy = strategy
+            w_list.lstorage = strategy.erase((w_item, times))
+            return True
+        if w_list.strategy is self.space.fromcache(UnicodeListStrategy):
+            w_item = w_list.getitem(0)
+            assert isinstance(w_item, W_UnicodeObject)
+            strategy = self.space.fromcache(RepeatListStrategy)
+            w_list.strategy = strategy
+            w_list.lstorage = strategy.erase((w_item, times))
+            return True
+        if w_list.strategy is self.space.fromcache(BytesListStrategy):
+            w_item = w_list.getitem(0)
+            assert isinstance(w_item, W_BytesObject)
+            strategy = self.space.fromcache(RepeatListStrategy)
+            w_list.strategy = strategy
+            w_list.lstorage = strategy.erase((w_item, times))
+            return True
+        if w_list.strategy is self.space.fromcache(BaseRangeListStrategy):
+            w_item = w_list.getitem(0)
+            assert isinstance(w_item, W_IntObject)
+            strategy = self.space.fromcache(RepeatListStrategy)
+            w_list.strategy = strategy
+            w_list.lstorage = strategy.erase((w_item, times))
+            return True
+        return False
+
     def inplace_mul(self, w_list, times):
+        assert w_list.strategy is not self.space.fromcache(RepeatListStrategy)
+        if times <= 0:
+            #XXX switch_to_empty() or clear()
+            strategy = self.space.fromcache(EmptyListStrategy)
+            w_list.strategy = strategy
+            w_list.lstorage = strategy.erase(None)
+            return
+        if w_list.length() == 1:
+            if self.switch_to_repeat_strategy_inplace(w_list, times):
+                return
         l = self.unerase(w_list.lstorage)
         l *= times
 
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
@@ -4,7 +4,7 @@
     W_ListObject, EmptyListStrategy, ObjectListStrategy, IntegerListStrategy,
     FloatListStrategy, BytesListStrategy, RangeListStrategy,
     SimpleRangeListStrategy, make_range_list, UnicodeListStrategy,
-    IntOrFloatListStrategy)
+    IntOrFloatListStrategy, make_repeat_list, RepeatListStrategy)
 from pypy.objspace.std import listobject
 from pypy.objspace.std.test.test_listobject import TestW_ListObject
 
@@ -588,6 +588,397 @@
         l3 = l1.descr_add(self.space, l2)
         assert self.space.eq_w(l3, W_ListObject(self.space, 
[self.space.wrap(1), self.space.wrap(2), self.space.wrap(3), 
self.space.wrap(4), self.space.wrap(5)]))
 
+    def test_repeatlist_from_other_strategy(self):
+        l1 = W_ListObject(self.space, [self.space.wrap(42)])
+        assert l1.strategy == self.space.fromcache(IntegerListStrategy)
+        l2 = l1.mul(3)
+        assert l1.strategy == self.space.fromcache(IntegerListStrategy)
+        assert l1.length() == 1
+        assert self.space.eq_w(l1.descr_getitem(self.space, 
self.space.wrap(0)), self.space.wrap(42))
+        assert l2.strategy == self.space.fromcache(RepeatListStrategy)
+        assert l2.length() == 3
+        assert self.space.eq_w(l2.descr_getitem(self.space, 
self.space.wrap(0)), self.space.wrap(42))
+
+    def test_repeatlist_from_other_strategy_imul(self):
+        l1 = W_ListObject(self.space, [self.space.wrap(42)])
+        assert l1.strategy == self.space.fromcache(IntegerListStrategy)
+        l1.inplace_mul(3)
+        assert l1.strategy == self.space.fromcache(RepeatListStrategy)
+        assert l1.length() == 3
+        assert self.space.eq_w(l1.descr_getitem(self.space, 
self.space.wrap(0)), self.space.wrap(42))
+
+    def test_repeatlist_from_other_strategy_imul_neg(self):
+        l1 = W_ListObject(self.space, [self.space.wrap(42)])
+        assert l1.strategy == self.space.fromcache(IntegerListStrategy)
+        l1.inplace_mul(-3)
+        assert l1.strategy == self.space.fromcache(EmptyListStrategy)
+        assert l1.length() == 0
+
+    def test_repeatlist_add(self):
+        l1 = make_repeat_list(self.space, self.space.wrap(None), 2)
+        l2 = make_repeat_list(self.space, self.space.wrap(None), 1)
+        l3 = l1.descr_add(self.space, l2)
+        assert self.space.eq_w(l3, W_ListObject(self.space, 
[self.space.wrap(None), self.space.wrap(None), self.space.wrap(None)]))
+        assert l3.strategy == self.space.fromcache(RepeatListStrategy)
+        l2 = W_ListObject(self.space, [self.space.wrap(None)])
+        l3 = l1.descr_add(self.space, l2)
+        assert self.space.eq_w(l3, W_ListObject(self.space, 
[self.space.wrap(None), self.space.wrap(None), self.space.wrap(None)]))
+        assert l3.strategy == self.space.fromcache(ObjectListStrategy)
+
+    def test_repeatlist_deleteslice(self):
+        l1 = make_repeat_list(self.space, self.space.wrap(None), 42)
+        assert l1.strategy == self.space.fromcache(RepeatListStrategy)
+        assert l1.length() == 42
+        assert self.space.eq_w(l1.descr_getitem(self.space, 
self.space.wrap(0)), self.space.wrap(None))
+        l1.deleteslice(0, 1, 0)
+        assert l1.strategy == self.space.fromcache(RepeatListStrategy)
+        assert l1.length() == 42
+        assert self.space.eq_w(l1.descr_getitem(self.space, 
self.space.wrap(0)), self.space.wrap(None))
+        l1.deleteslice(0, 1, 12)
+        assert l1.strategy == self.space.fromcache(RepeatListStrategy)
+        assert l1.length() == 30
+        assert self.space.eq_w(l1.descr_getitem(self.space, 
self.space.wrap(0)), self.space.wrap(None))
+        l1.deleteslice(0, 1, 30)
+        assert l1.strategy == self.space.fromcache(RepeatListStrategy)
+        assert l1.length() == 0
+
+    def test_repeatlist_empty_getitem(self):
+        l1 = make_repeat_list(self.space, self.space.wrap(None), 1)
+        assert l1.strategy == self.space.fromcache(RepeatListStrategy)
+        assert l1.length() == 1
+        l1.pop_end()
+        assert l1.strategy == self.space.fromcache(RepeatListStrategy)
+        assert l1.length() == 0
+        from pypy.interpreter.error import OperationError
+        try:
+            l1.descr_getitem(self.space, self.space.wrap(0))
+        except OperationError as e:
+            if not e.match(self.space, self.space.w_IndexError):
+                raise
+        else:
+            assert False, "Did not raise IndexError"
+
+    def test_repeatlist_setitem(self):
+        l1 = make_repeat_list(self.space, self.space.wrap(None), 3)
+        assert l1.strategy == self.space.fromcache(RepeatListStrategy)
+        assert l1.length() == 3
+        assert self.space.eq_w(l1, W_ListObject(self.space, 
[self.space.wrap(None), self.space.wrap(None), self.space.wrap(None)]))
+        l1.setitem(1, self.space.wrap(None))
+        assert l1.strategy == self.space.fromcache(RepeatListStrategy)
+        assert l1.length() == 3
+        assert self.space.eq_w(l1, W_ListObject(self.space, 
[self.space.wrap(None), self.space.wrap(None), self.space.wrap(None)]))
+        l1.setitem(1, self.space.wrap(42))
+        assert l1.strategy == self.space.fromcache(ObjectListStrategy)
+        assert l1.length() == 3
+        assert self.space.eq_w(l1, W_ListObject(self.space, 
[self.space.wrap(None), self.space.wrap(42), self.space.wrap(None)]))
+
+        l1 = make_repeat_list(self.space, self.space.wrap(42), 3)
+        assert l1.strategy == self.space.fromcache(RepeatListStrategy)
+        assert l1.length() == 3
+        assert self.space.eq_w(l1, W_ListObject(self.space, 
[self.space.wrap(42), self.space.wrap(42), self.space.wrap(42)]))
+        l1.setitem(1, self.space.wrap(21))
+        assert l1.strategy == self.space.fromcache(IntegerListStrategy)
+        assert l1.length() == 3
+        assert self.space.eq_w(l1, W_ListObject(self.space, 
[self.space.wrap(42), self.space.wrap(21), self.space.wrap(42)]))
+
+        l1 = make_repeat_list(self.space, self.space.wrap(42), 3)
+        from pypy.interpreter.error import OperationError
+        try:
+            l1.setitem(10, self.space.wrap(42))
+        except IndexError:
+            pass
+        else:
+            assert False, "Did not raise IndexError"
+
+    def test_repeatlist_insert(self):
+        l1 = make_repeat_list(self.space, self.space.wrap(None), 2)
+        assert l1.strategy == self.space.fromcache(RepeatListStrategy)
+        assert l1.length() == 2
+        assert self.space.eq_w(l1, W_ListObject(self.space, 
[self.space.wrap(None), self.space.wrap(None)]))
+        l1.insert(0, self.space.wrap(None))
+        assert l1.strategy == self.space.fromcache(RepeatListStrategy)
+        assert l1.length() == 3
+        assert self.space.eq_w(l1, W_ListObject(self.space, 
[self.space.wrap(None), self.space.wrap(None), self.space.wrap(None)]))
+        l1.insert(1, self.space.wrap(42))
+        assert l1.strategy == self.space.fromcache(ObjectListStrategy)
+        assert l1.length() == 4
+        assert self.space.eq_w(l1, W_ListObject(self.space, 
[self.space.wrap(None), self.space.wrap(42), self.space.wrap(None), 
self.space.wrap(None)]))
+
+        l1 = make_repeat_list(self.space, self.space.wrap(42), 2)
+        assert l1.strategy == self.space.fromcache(RepeatListStrategy)
+        assert l1.length() == 2
+        assert self.space.eq_w(l1, W_ListObject(self.space, 
[self.space.wrap(42), self.space.wrap(42)]))
+        l1.insert(0, self.space.wrap(21))
+        assert l1.strategy == self.space.fromcache(IntegerListStrategy)
+        assert l1.length() == 3
+        assert self.space.eq_w(l1, W_ListObject(self.space, 
[self.space.wrap(21), self.space.wrap(42), self.space.wrap(42)]))
+
+        l1 = make_repeat_list(self.space, self.space.wrap(42), 3)
+        from pypy.interpreter.error import OperationError
+        try:
+            l1.insert(10, self.space.wrap(42))
+        except IndexError:
+            pass
+        else:
+            assert False, "Did not raise IndexError"
+
+    def test_repeatlist_reverse(self):
+        l1 = make_repeat_list(self.space, self.space.wrap(None), 2)
+        assert l1.strategy == self.space.fromcache(RepeatListStrategy)
+        assert l1.length() == 2
+        assert self.space.eq_w(l1, W_ListObject(self.space, 
[self.space.wrap(None), self.space.wrap(None)]))
+        l1.reverse()
+        assert l1.strategy == self.space.fromcache(RepeatListStrategy)
+        assert l1.length() == 2
+        assert self.space.eq_w(l1, W_ListObject(self.space, 
[self.space.wrap(None), self.space.wrap(None)]))
+
+    def test_repeatlist_setslice(self):
+        l1 = make_repeat_list(self.space, self.space.wrap(None), 3)
+        l2 = make_repeat_list(self.space, self.space.wrap(None), 2)
+        assert l1.strategy == self.space.fromcache(RepeatListStrategy)
+        assert l1.length() == 3
+        assert l2.strategy == self.space.fromcache(RepeatListStrategy)
+        assert l2.length() == 2
+        assert self.space.eq_w(l1, W_ListObject(self.space, 
[self.space.wrap(None), self.space.wrap(None), self.space.wrap(None)]))
+        assert self.space.eq_w(l2, W_ListObject(self.space, 
[self.space.wrap(None), self.space.wrap(None)]))
+        l1.setslice(1, 1, 1, l2)
+        assert l1.strategy == self.space.fromcache(RepeatListStrategy)
+        assert l1.length() == 4
+        assert self.space.eq_w(l1, W_ListObject(self.space, 
[self.space.wrap(None), self.space.wrap(None), self.space.wrap(None), 
self.space.wrap(None)]))
+
+        l1 = make_repeat_list(self.space, self.space.wrap(42), 2)
+        l2 = make_range_list(self.space, 1, 3, 3)
+        l1.setslice(1, 1, 1, l2)
+        assert l1.strategy == self.space.fromcache(ObjectListStrategy)
+        assert l1.length() == 4
+        assert self.space.eq_w(l1, W_ListObject(self.space, 
[self.space.wrap(42), self.space.wrap(1), self.space.wrap(4), 
self.space.wrap(7)]))
+
+    def test_repeatlist_mul(self):
+        l1 = make_repeat_list(self.space, self.space.wrap(None), 2)
+        assert l1.strategy == self.space.fromcache(RepeatListStrategy)
+        assert l1.length() == 2
+        l2 = l1.mul(3)
+        assert l1.strategy == self.space.fromcache(RepeatListStrategy)
+        assert l2.strategy == self.space.fromcache(RepeatListStrategy)
+        assert l1.length() == 2
+        assert l2.length() == 6
+        assert self.space.eq_w(l1.descr_getitem(self.space, 
self.space.wrap(0)), self.space.wrap(None))
+        assert self.space.eq_w(l2.descr_getitem(self.space, 
self.space.wrap(0)), self.space.wrap(None))
+        assert self.space.eq_w(l2, W_ListObject(self.space, 
[self.space.wrap(None), self.space.wrap(None), self.space.wrap(None),
+                                                             
self.space.wrap(None), self.space.wrap(None), self.space.wrap(None)]))
+
+    def test_repeatlist_mul_other(self):
+        l1 = W_ListObject(self.space, [self.space.wrap(None)])
+        assert l1.strategy == self.space.fromcache(ObjectListStrategy)
+        assert l1.length() == 1
+        l2 = l1.mul(3)
+        assert l1.strategy == self.space.fromcache(ObjectListStrategy)
+        assert l2.strategy == self.space.fromcache(RepeatListStrategy)
+        assert l1.length() == 1
+        assert l2.length() == 3
+        assert self.space.eq_w(l1.descr_getitem(self.space, 
self.space.wrap(0)), self.space.wrap(None))
+        assert self.space.eq_w(l2.descr_getitem(self.space, 
self.space.wrap(0)), self.space.wrap(None))
+        assert self.space.eq_w(l2, W_ListObject(self.space, 
[self.space.wrap(None), self.space.wrap(None), self.space.wrap(None)]))
+
+    def test_repeatlist_imul(self):
+        l1 = make_repeat_list(self.space, self.space.wrap(None), 2)
+        assert l1.strategy == self.space.fromcache(RepeatListStrategy)
+        assert l1.length() == 2
+        l1.inplace_mul(3)
+        assert l1.strategy == self.space.fromcache(RepeatListStrategy)
+        assert l1.length() == 6
+        assert self.space.eq_w(l1.descr_getitem(self.space, 
self.space.wrap(0)), self.space.wrap(None))
+        assert self.space.eq_w(l1, W_ListObject(self.space, 
[self.space.wrap(None), self.space.wrap(None), self.space.wrap(None),
+                                                             
self.space.wrap(None), self.space.wrap(None), self.space.wrap(None)]))
+
+    def test_repeatlist_append(self):
+        # Same item
+        l1 = make_repeat_list(self.space, self.space.wrap(None), 2)
+        l1.append(self.space.wrap(None))
+        assert self.space.eq_w(l1, W_ListObject(self.space, 
[self.space.wrap(None), self.space.wrap(None), self.space.wrap(None)]))
+        assert l1.strategy == self.space.fromcache(RepeatListStrategy)
+        # Same type => IntegerListStrategy
+        l2 = make_repeat_list(self.space, self.space.wrap(42), 2)
+        assert l2.strategy == self.space.fromcache(RepeatListStrategy)
+        l2.append(self.space.wrap(21))
+        assert l2.strategy == self.space.fromcache(IntegerListStrategy)
+        assert self.space.eq_w(l2, W_ListObject(self.space, 
[self.space.wrap(42), self.space.wrap(42), self.space.wrap(21)]))
+        # Different type => ObjectListStrategy
+        l3 = make_repeat_list(self.space, self.space.wrap(42), 2)
+        l3.append(self.space.wrap(21.0))
+        assert self.space.eq_w(l3, W_ListObject(self.space, 
[self.space.wrap(42), self.space.wrap(42), self.space.wrap(21.0)]))
+        assert l3.strategy == self.space.fromcache(ObjectListStrategy)
+        # Stays at ObjectListStrategy
+        l = make_repeat_list(self.space, self.space.wrap(None), 2)
+        assert isinstance(l.strategy, RepeatListStrategy)
+        l.append(self.space.wrap(None))
+        assert isinstance(l.strategy, RepeatListStrategy)
+        l.append(self.space.wrap("string"))
+        assert isinstance(l.strategy, ObjectListStrategy)
+        l.append(self.space.wrap(None))
+        assert isinstance(l.strategy, ObjectListStrategy)
+        # Other types
+        l = make_repeat_list(self.space, self.space.wrap(b'qwerty'), 2)
+        assert isinstance(l.strategy, RepeatListStrategy)
+        l.append(self.space.wrap(b'azerty'))
+        assert isinstance(l.strategy, BytesListStrategy)
+        l = make_repeat_list(self.space, self.space.wrap(u'azerty'), 2)
+        assert isinstance(l.strategy, RepeatListStrategy)
+        l.append(self.space.wrap(u'qwerty'))
+        assert isinstance(l.strategy, UnicodeListStrategy)
+        l = make_repeat_list(self.space, self.space.wrap(42.0), 2)
+        assert isinstance(l.strategy, RepeatListStrategy)
+        l.append(self.space.wrap(21.0))
+        assert isinstance(l.strategy, FloatListStrategy)
+
+    def test_repeatlist_find(self):
+        # Same item
+        l1 = make_repeat_list(self.space, self.space.wrap(None), 2)
+        idx = l1.find(self.space.wrap(None))
+        assert idx == 0
+        assert l1.strategy == self.space.fromcache(RepeatListStrategy)
+        # Same integer
+        l2 = make_repeat_list(self.space, self.space.wrap(42), 2)
+        idx = l2.find(self.space.wrap(42))
+        assert idx == 0
+        # Should still find it
+        idx = l2.find(self.space.wrap(42.0))
+        assert idx == 0
+        # Different integer
+        try:
+            l2.find(self.space.wrap(21))
+        except ValueError:
+            pass
+        else:
+            assert False, "Did not raise ValueError"
+        # Different type
+        try:
+            l2.find(self.space.wrap(21.0))
+        except ValueError:
+            pass
+        else:
+            assert False, "Did not raise ValueError"
+
+    def test_repeatlist_base(self):
+        l1 = make_repeat_list(self.space, self.space.wrap(None), 0)
+        assert l1.strategy == self.space.fromcache(EmptyListStrategy)
+        l1 = make_repeat_list(self.space, self.space.wrap(None), 1000000000)
+        assert l1.strategy == self.space.fromcache(RepeatListStrategy)
+        assert l1.length() == 1000000000
+
+    def test_repeatlist_big(self):
+        l1 = make_repeat_list(self.space, self.space.wrap(42), 1)
+        w_forty_two = self.space.wrap(42)
+
+        i = 100000 - 1
+        while i > 0:
+            l1.append(w_forty_two)
+            i -= 1
+        assert l1.strategy == self.space.fromcache(RepeatListStrategy)
+        assert l1.length() == 100000
+
+        i = 100000 - 1
+        while i > 0:
+            item = l1.pop(0)
+            assert self.space.eq_w(item, w_forty_two)
+            i -= 1
+        assert l1.strategy == self.space.fromcache(RepeatListStrategy)
+        assert l1.length() == 1
+
+    def test_repeatlist_getitem(self):
+        l1 = make_repeat_list(self.space, self.space.wrap(None), 2)
+        assert self.space.eq_w(l1.descr_getitem(self.space, 
self.space.wrap(0)), self.space.wrap(None))
+        assert l1.strategy == self.space.fromcache(RepeatListStrategy)
+
+    def test_repeatlist_extend_with_empty(self):
+        l = make_repeat_list(self.space, self.space.wrap(None), 2)
+        assert isinstance(l.strategy, RepeatListStrategy)
+        l.extend(W_ListObject(self.space, []))
+        assert isinstance(l.strategy, RepeatListStrategy)
+
+    def test_repeatlist_pop(self):
+        l = make_repeat_list(self.space, self.space.wrap(None), 42)
+        assert isinstance(l.strategy, RepeatListStrategy)
+        v = l.pop(5)
+        assert self.space.eq_w(v, self.space.wrap(None))
+        assert isinstance(l.strategy, RepeatListStrategy)
+
+        l = make_repeat_list(self.space, self.space.wrap(42), 5)
+        assert isinstance(l.strategy, RepeatListStrategy)
+        assert l.length() == 5
+        v = l.pop(0)
+        assert l.length() == 4
+        assert self.space.eq_w(v, self.space.wrap(42))
+        assert isinstance(l.strategy, RepeatListStrategy)
+        v = l.pop(l.length() - 1)
+        assert l.length() == 3
+        assert self.space.eq_w(v, self.space.wrap(42))
+        assert isinstance(l.strategy, RepeatListStrategy)
+        v = l.pop_end()
+        assert l.length() == 2
+        assert self.space.eq_w(v, self.space.wrap(42))
+        assert isinstance(l.strategy, RepeatListStrategy)
+        l.pop(0)
+        l.pop(0)
+        assert l.length() == 0
+        assert isinstance(l.strategy, RepeatListStrategy)
+        try:
+            l.pop(0)
+        except IndexError:
+            pass
+        else:
+            assert False, "Did not raise IndexError"
+        assert l.length() == 0
+        assert isinstance(l.strategy, RepeatListStrategy)
+        try:
+            l.pop_end()
+        except IndexError:
+            pass
+        else:
+            assert False, "Did not raise IndexError"
+        assert l.length() == 0
+        assert isinstance(l.strategy, RepeatListStrategy)
+
+    def test_repeatlist_getslice(self):
+        l = make_repeat_list(self.space, self.space.wrap(0), 42)
+        assert isinstance(l.strategy, RepeatListStrategy)
+        s = l.getslice(3, 6, 1, 2)
+        assert isinstance(l.strategy, RepeatListStrategy)
+        assert isinstance(s.strategy, RepeatListStrategy)
+        assert self.space.eq_w(s, W_ListObject(self.space, 
[self.space.wrap(0), self.space.wrap(0), self.space.wrap(0)]))
+        s = l.getslice(3, 6, 2, 2)
+        assert self.space.eq_w(s, W_ListObject(self.space, 
[self.space.wrap(0), self.space.wrap(0)]))
+        s = l.getslice(3, 7, 2, 2)
+        assert self.space.eq_w(s, W_ListObject(self.space, 
[self.space.wrap(0), self.space.wrap(0)]))
+        s = l.getslice(3, 8, 2, 2)
+        assert self.space.eq_w(s, W_ListObject(self.space, 
[self.space.wrap(0), self.space.wrap(0), self.space.wrap(0)]))
+        s = l.getslice(3, 8, 3, 2)
+        assert self.space.eq_w(s, W_ListObject(self.space, 
[self.space.wrap(0), self.space.wrap(0)]))
+        s = l.getslice(3, 9, 3, 2)
+        assert self.space.eq_w(s, W_ListObject(self.space, 
[self.space.wrap(0), self.space.wrap(0)]))
+        s = l.getslice(3, 10, 3, 2)
+        assert self.space.eq_w(s, W_ListObject(self.space, 
[self.space.wrap(0), self.space.wrap(0), self.space.wrap(0)]))
+        s = l.getslice(3, 6, -1, 2)
+        assert isinstance(l.strategy, RepeatListStrategy)
+        assert isinstance(s.strategy, EmptyListStrategy)
+        s = l.getslice(-3, -6, -1, 2)
+        assert self.space.eq_w(s, W_ListObject(self.space, 
[self.space.wrap(0), self.space.wrap(0), self.space.wrap(0)]))
+        assert isinstance(l.strategy, RepeatListStrategy)
+        assert isinstance(s.strategy, RepeatListStrategy)
+        s = l.getslice(6, 3, -1, 2)
+        assert self.space.eq_w(s, W_ListObject(self.space, 
[self.space.wrap(0), self.space.wrap(0), self.space.wrap(0)]))
+        assert isinstance(l.strategy, RepeatListStrategy)
+        assert isinstance(s.strategy, RepeatListStrategy)
+
+    def test_repeatlist_recursion(self):
+        rl = make_repeat_list(self.space, self.space.wrap(42), 2)
+        ol = W_ListObject(self.space, [self.space.wrap(None), 
self.space.wrap(False)])
+        # This should not endlessly recurse into a AULS.append() -> 
OLS.is_correct_type() loop
+        ol.append(rl)
+        assert ol.length() == 3
+        assert self.space.eq_w(ol, W_ListObject(self.space, 
[self.space.wrap(None),
+            self.space.wrap(False), W_ListObject(self.space, 
[self.space.wrap(42), self.space.wrap(42)])]))
+
     def test_unicode(self):
         l1 = W_ListObject(self.space, [self.space.wrap("eins"), 
self.space.wrap("zwei")])
         assert isinstance(l1.strategy, BytesListStrategy)
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to