[pypy-commit] pypy default: issue1266: remove the more brittle RangeListStrategy optimizations entirely,

pjenvey noreply at buildbot.pypy.org
Fri Sep 21 19:50:22 CEST 2012


Author: Philip Jenvey <pjenvey at underboss.org>
Branch: 
Changeset: r57458:ad495c36a765
Date: 2012-09-21 10:44 -0700
http://bitbucket.org/pypy/pypy/changeset/ad495c36a765/

Log:	issue1266: remove the more brittle RangeListStrategy optimizations
	entirely, they have overflow bugs and aren't that useful anyway

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
@@ -579,25 +579,11 @@
     _getitems_range_unroll = jit.unroll_safe(func_with_new_name(_getitems_range, "_getitems_range_unroll"))
 
     def getslice(self, w_list, start, stop, step, length):
-        v = self.unerase(w_list.lstorage)
-        old_step = v[1]
-
-        new_start = self._getitem_unwrapped(w_list, start)
-        new_step = old_step * step
-        return make_range_list(self.space, new_start, new_step, length)
+        self.switch_to_integer_strategy(w_list)
+        return w_list.getslice(start, stop, step, length)
 
     def append(self, w_list, w_item):
         if is_W_IntObject(w_item):
-            l = self.unerase(w_list.lstorage)
-            length = l[2]
-            if length:
-                last_in_range = self._getitem_unwrapped(w_list, -1)
-                step = l[1]
-                if self.unwrap(w_item) - step == last_in_range:
-                    new = self.erase((l[0], step, length + 1))
-                    w_list.lstorage = new
-                    return
-
             self.switch_to_integer_strategy(w_list)
         else:
             w_list.switch_to_object_strategy()
@@ -643,13 +629,10 @@
         w_list.setslice(start, step, slicelength, sequence_w)
 
     def sort(self, w_list, reverse):
-        start, step, length = self.unerase(w_list.lstorage)
+        step = self.unerase(w_list.lstorage)[1]
         if step > 0 and reverse or step < 0 and not reverse:
-            start = start + step * (length - 1)
-            step = step * (-1)
-        else:
-            return
-        w_list.lstorage = self.erase((start, step, length))
+            self.switch_to_integer_strategy(w_list)
+            w_list.sort(reverse)
 
     def insert(self, w_list, index, w_item):
         self.switch_to_integer_strategy(w_list)
@@ -660,12 +643,8 @@
         w_list.extend(items_w)
 
     def reverse(self, w_list):
-        v = self.unerase(w_list.lstorage)
-        last = self._getitem_unwrapped(w_list, -1)
-        length = v[2]
-        skip = v[1]
-        new = self.erase((last, -skip, length))
-        w_list.lstorage = new
+        self.switch_to_integer_strategy(w_list)
+        w_list.reverse()
 
 class AbstractUnwrappedStrategy(object):
     _mixin_ = True
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
@@ -1352,6 +1352,29 @@
         l.append(1)
         assert l == [1]
 
+        l = range(1)
+        l.pop()
+        # would previously crash
+        l.reverse()
+        assert l == []
+
+    def test_issue1266_ovf(self):
+        import sys
+
+        l = range(0, sys.maxint, sys.maxint)
+        l.append(sys.maxint)
+        # -2 would be next in the range sequence if overflow were
+        # allowed
+        l.append(-2)
+        assert l == [0, sys.maxint, -2]
+        assert -2 in l
+
+        l = range(-sys.maxint, sys.maxint, sys.maxint // 10)
+        item11 = l[11]
+        assert l[::11] == [-sys.maxint, item11]
+        assert item11 in l[::11]
+
+
 class AppTestWithoutStrategies(object):
 
     def setup_class(cls):
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,3 +1,4 @@
+import sys
 from pypy.objspace.std.listobject import W_ListObject, EmptyListStrategy, ObjectListStrategy, IntegerListStrategy, FloatListStrategy, StringListStrategy, RangeListStrategy, make_range_list
 from pypy.objspace.std import listobject
 from pypy.objspace.std.test.test_listobject import TestW_ListObject
@@ -325,13 +326,13 @@
         l.pop(l.length()-1)
         assert isinstance(l.strategy, RangeListStrategy)
         l.append(self.space.wrap(5))
-        assert isinstance(l.strategy, RangeListStrategy)
+        assert isinstance(l.strategy, IntegerListStrategy)
 
         # complex list
         l = make_range_list(self.space, 1,3,5)
         assert isinstance(l.strategy, RangeListStrategy)
         l.append(self.space.wrap(16))
-        assert isinstance(l.strategy, RangeListStrategy)
+        assert isinstance(l.strategy, IntegerListStrategy)
 
     def test_empty_range(self):
         l = make_range_list(self.space, 0, 0, 0)
@@ -344,12 +345,28 @@
 
         assert isinstance(l.strategy, RangeListStrategy)
 
+    def test_range_getslice_ovf(self):
+        l = make_range_list(self.space, -sys.maxint, sys.maxint // 10, 21)
+        assert isinstance(l.strategy, RangeListStrategy)
+        l2 = l.getslice(0, 21, 11, 2)
+        assert isinstance(l2.strategy, IntegerListStrategy)
+
     def test_range_setslice(self):
         l = make_range_list(self.space, 1, 3, 5)
         assert isinstance(l.strategy, RangeListStrategy)
         l.setslice(0, 1, 3, W_ListObject(self.space, [self.space.wrap(1), self.space.wrap(2), self.space.wrap(3)]))
         assert isinstance(l.strategy, IntegerListStrategy)
 
+    def test_range_reverse_ovf(self):
+        l = make_range_list(self.space, 0, -sys.maxint - 1, 1)
+        assert isinstance(l.strategy, RangeListStrategy)
+        l.reverse()
+        assert isinstance(l.strategy, IntegerListStrategy)
+
+        l = make_range_list(self.space, 0, -sys.maxint - 1, 1)
+        l.sort(False)
+        assert isinstance(l.strategy, IntegerListStrategy)
+
     def test_copy_list(self):
         l1 = W_ListObject(self.space, [self.space.wrap(1), self.space.wrap(2), self.space.wrap(3)])
         l2 = l1.clone()
diff --git a/pypy/objspace/std/test/test_rangeobject.py b/pypy/objspace/std/test/test_rangeobject.py
--- a/pypy/objspace/std/test/test_rangeobject.py
+++ b/pypy/objspace/std/test/test_rangeobject.py
@@ -32,7 +32,7 @@
         for i in r[10:15]:
             result.append(i)
         assert result == [21, 23, 25, 27, 29]
-        assert self.not_forced(r)
+        assert not self.not_forced(r)
 
     def test_getitem_extended_slice(self):
         result = []
@@ -40,7 +40,7 @@
         for i in r[40:30:-2]:
             result.append(i)
         assert result == [81, 77, 73, 69, 65]
-        assert self.not_forced(r)
+        assert not self.not_forced(r)
 
     def test_empty_range(self):
         r = range(10, 10)
@@ -62,7 +62,7 @@
     def test_reverse(self):
         r = range(10)
         r.reverse()
-        assert self.not_forced(r)
+        assert not self.not_forced(r)
         assert r == range(9, -1, -1)
         r = range(3)
         r[0] = 1


More information about the pypy-commit mailing list