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