[Jython-checkins] jython: Fix index out of range in slice deletion from sequences.

jeff.allen jython-checkins at python.org
Sun Jul 8 15:22:55 CEST 2012


http://hg.python.org/jython/rev/cdf3485e1ba6
changeset:   6787:cdf3485e1ba6
parent:      6781:bf3a1d3eae8c
user:        Jeff Allen <ja...py at farowl.co.uk>
date:        Sun Jul 08 14:00:01 2012 +0100
summary:
  Fix index out of range in slice deletion from sequences.
The loop in SequenceIndexDelegate.delSlice generated an invalid index for size approaching MAXINT. Fixes a failure in test_bytes.py and removes a skip from list_tests.py .

files:
  Lib/test/list_tests.py                         |   8 +-
  src/org/python/core/SequenceIndexDelegate.java |  37 +++++----
  2 files changed, 25 insertions(+), 20 deletions(-)


diff --git a/Lib/test/list_tests.py b/Lib/test/list_tests.py
--- a/Lib/test/list_tests.py
+++ b/Lib/test/list_tests.py
@@ -529,11 +529,9 @@
         a[::2] = tuple(range(5))
         self.assertEqual(a, self.type2test([0, 1, 1, 3, 2, 5, 3, 7, 4, 9]))
 
-        #FIXME: not working on Jython
-        if not test_support.is_jython:
-            # test issue7788
-            a = self.type2test(range(10))
-            del a[9::1<<333]
+        # test issue7788
+        a = self.type2test(range(10))
+        del a[9::1<<333]
 
     # XXX: CPython specific, PyList doesn't len() during init
     def _test_constructor_exception_handling(self):
diff --git a/src/org/python/core/SequenceIndexDelegate.java b/src/org/python/core/SequenceIndexDelegate.java
--- a/src/org/python/core/SequenceIndexDelegate.java
+++ b/src/org/python/core/SequenceIndexDelegate.java
@@ -50,8 +50,8 @@
         if (idx.isIndex()) {
             delItem(checkIdx(idx.asIndex(Py.IndexError)));
         } else if (idx instanceof PySlice) {
-            int[] indices = ((PySlice)idx).indicesEx(len());
-            delSlice(indices[0], indices[1], indices[2]);
+            PySlice slice = (PySlice) idx;
+            delSlice(slice.indicesEx(len()));
         } else {
             throw Py.TypeError(getTypeName() + " indices must be integers");
         }
@@ -109,21 +109,28 @@
         }
     }
 
-    private void delSlice(int start, int stop, int step) {
-        if(step == 1) {
-            if (stop > start) {
-                delItems(start, stop);
+    private void delSlice(int[] indices) {
+        int p = indices[0], step = indices[2], count = indices[3];
+        if (step > 1) {
+            /*
+             * Key observation: each deletion causes material to the right (not yet visited) to move
+             * one place left, so the deletion pointer moves by step-1 not by step as might be
+             * expected.
+             */
+            step = step - 1;
+            for (; count > 0; --count, p += step) {
+                delItem(p);
             }
-        } else if(step > 1) {
-            for(int i = start; i < stop; i += step) {
-                delItem(i);
-                i--;
-                stop--;
+        } else if (step < 1) {
+            // Deletion pointer moves leftwards, and moving data is to the right
+            for (; count > 0; --count, p += step) {
+                delItem(p);
             }
-        } else if(step < 0) {
-            for(int i = start; i >= 0 && i > stop; i += step) {
-                delItem(i);
+        } else { // step == 1, since it is never == 0
+            // Slice is contiguous: use range delete
+            if (count > 0) {
+                delItems(p, p + count);
             }
         }
     }
-}
\ No newline at end of file
+}

-- 
Repository URL: http://hg.python.org/jython


More information about the Jython-checkins mailing list