Author: Armin Rigo <[email protected]>
Branch: flow-no-local-exception
Changeset: r65873:9156c47391d7
Date: 2013-08-01 10:42 +0200
http://bitbucket.org/pypy/pypy/changeset/9156c47391d7/

Log:    in-progress

diff --git a/pypy/objspace/std/bytearrayobject.py 
b/pypy/objspace/std/bytearrayobject.py
--- a/pypy/objspace/std/bytearrayobject.py
+++ b/pypy/objspace/std/bytearrayobject.py
@@ -16,6 +16,7 @@
 from pypy.objspace.std.stringobject import W_StringObject
 from pypy.objspace.std.unicodeobject import W_UnicodeObject
 from pypy.objspace.std.util import get_positive_index
+from pypy.objspace.std.util import ListIndexError, getuindex
 from rpython.rlib.rstring import StringBuilder
 
 
@@ -93,9 +94,9 @@
     except AttributeError:
         w_IndexError = None
     index = space.getindex_w(w_index, w_IndexError, "bytearray index")
-    try:
+    if index < len(w_bytearray.data):
         return space.newint(ord(w_bytearray.data[index]))
-    except IndexError:
+    else:
         raise OperationError(space.w_IndexError,
                              space.wrap("bytearray index out of range"))
 
@@ -394,13 +395,14 @@
 def bytearray_pop__Bytearray_Int(space, w_bytearray, w_idx):
     index = space.int_w(w_idx)
     try:
-        result = w_bytearray.data.pop(index)
-    except IndexError:
+        uindex = getuindex(w_bytearray.data, index)
+    except ListIndexError:
         if not w_bytearray.data:
             raise OperationError(space.w_IndexError, space.wrap(
                 "pop from empty bytearray"))
         raise OperationError(space.w_IndexError, space.wrap(
             "pop index out of range"))
+    result = w_bytearray.data.pop(uindex)
     return space.wrap(ord(result))
 
 def bytearray_remove__Bytearray_ANY(space, w_bytearray, w_char):
@@ -570,11 +572,13 @@
 def setitem__Bytearray_ANY_ANY(space, w_bytearray, w_index, w_item):
     from pypy.objspace.std.bytearraytype import getbytevalue
     idx = space.getindex_w(w_index, space.w_IndexError, "bytearray index")
+    byte = getbytevalue(space, w_item)
     try:
-        w_bytearray.data[idx] = getbytevalue(space, w_item)
-    except IndexError:
+        uindex = getuindex(w_bytearray.data, idx)
+    except ListIndexError:
         raise OperationError(space.w_IndexError,
                              space.wrap("bytearray index out of range"))
+    w_bytearray.data[uindex] = byte
 
 def setitem__Bytearray_Slice_ANY(space, w_bytearray, w_slice, w_other):
     oldsize = len(w_bytearray.data)
@@ -585,11 +589,11 @@
 def delitem__Bytearray_ANY(space, w_bytearray, w_idx):
     idx = space.getindex_w(w_idx, space.w_IndexError, "bytearray index")
     try:
-        del w_bytearray.data[idx]
-    except IndexError:
+        uindex = getuindex(w_bytearray.data, idx)
+    except ListIndexError:
         raise OperationError(space.w_IndexError,
                              space.wrap("bytearray deletion index out of 
range"))
-    return space.w_None
+    del w_bytearray.data[uindex]
 
 def delitem__Bytearray_Slice(space, w_bytearray, w_slice):
     start, stop, step, slicelength = w_slice.indices4(space,
diff --git a/pypy/objspace/std/formatting.py b/pypy/objspace/std/formatting.py
--- a/pypy/objspace/std/formatting.py
+++ b/pypy/objspace/std/formatting.py
@@ -25,15 +25,14 @@
 
     def nextinputvalue(self):
         # return the next value in the tuple of input arguments
-        try:
+        if self.values_pos < len(self.values_w):
             w_result = self.values_w[self.values_pos]
-        except IndexError:
+            self.values_pos += 1
+            return w_result
+        else:
             space = self.space
             raise OperationError(space.w_TypeError, space.wrap(
                 'not enough arguments for format string'))
-        else:
-            self.values_pos += 1
-            return w_result
 
     def checkconsumed(self):
         if self.values_pos < len(self.values_w) and self.w_valuedict is None:
@@ -168,9 +167,9 @@
 
         def peekchr(self):
             # return the 'current' character
-            try:
+            if self.fmtpos < len(self.fmt):
                 return self.fmt[self.fmtpos]
-            except IndexError:
+            else:
                 space = self.space
                 raise OperationError(space.w_ValueError,
                                      space.wrap("incomplete format"))
@@ -185,9 +184,9 @@
             i0 = i
             pcount = 1
             while 1:
-                try:
+                if i < len(fmt):
                     c = fmt[i]
-                except IndexError:
+                else:
                     space = self.space
                     raise OperationError(space.w_ValueError,
                                          space.wrap("incomplete format key"))
diff --git a/pypy/objspace/std/frame.py b/pypy/objspace/std/frame.py
--- a/pypy/objspace/std/frame.py
+++ b/pypy/objspace/std/frame.py
@@ -9,6 +9,7 @@
 from pypy.objspace.std import intobject
 from pypy.objspace.std.multimethod import FailedToImplement
 from pypy.objspace.std.listobject import W_ListObject
+from pypy.objspace.std.util import ListIndexError
 
 
 class BaseFrame(PyFrame):
@@ -43,7 +44,7 @@
     if type(w_1) is W_ListObject and type(w_2) is intobject.W_IntObject:
         try:
             w_result = w_1.getitem(w_2.intval)
-        except IndexError:
+        except ListIndexError:
             raise OperationError(f.space.w_IndexError,
                 f.space.wrap("list index out of range"))
     else:
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
@@ -28,8 +28,8 @@
 from pypy.objspace.std.tupleobject import W_AbstractTupleObject
 from pypy.objspace.std.unicodeobject import W_UnicodeObject
 from pypy.objspace.std.util import get_positive_index, negate
+from pypy.objspace.std.util import ListIndexError, getuindex
 from rpython.rlib import debug, jit, rerased
-from rpython.rlib.rarithmetic import r_uint
 from rpython.rlib.listsort import make_timsort_class
 from rpython.rlib.objectmodel import (
     instantiate, newlist_hint, resizelist_hint, specialize)
@@ -38,10 +38,6 @@
 __all__ = ['W_ListObject', 'make_range_list', 'make_empty_list_with_size']
 
 
-class ListIndexError(Exception):
-    """A custom RPython class, raised by getitem() and similar methods."""
-
-
 UNROLL_CUTOFF = 5
 
 
@@ -1240,20 +1236,9 @@
     def length(self, w_list):
         return len(self.unerase(w_list.lstorage))
 
-    @staticmethod
-    def _getidx(l, index):
-        ulength = r_uint(len(l))
-        uindex = r_uint(index)
-        if uindex >= ulength:
-            # out of bounds -or- negative index
-            uindex += ulength
-            if uindex >= ulength:
-                raise ListIndexError
-        return uindex
-
     def getitem(self, w_list, index):
         l = self.unerase(w_list.lstorage)
-        uindex = self._getidx(l, index)
+        uindex = getuindex(l, index)
         return self.wrap(l[uindex])
 
     @jit.look_inside_iff(lambda self, w_list:
@@ -1331,7 +1316,7 @@
         l = self.unerase(w_list.lstorage)
 
         if self.is_correct_type(w_item):
-            uindex = self._getidx(l, index)
+            uindex = getuindex(l, index)
             l[uindex] = self.unwrap(w_item)
             return
 
@@ -1442,7 +1427,7 @@
 
     def pop(self, w_list, index):
         l = self.unerase(w_list.lstorage)
-        uindex = self._getidx(l, index)
+        uindex = getuindex(l, index)
         item = l.pop(uindex)
         w_item = self.wrap(item)
         return w_item
diff --git a/pypy/objspace/std/marshal_impl.py 
b/pypy/objspace/std/marshal_impl.py
--- a/pypy/objspace/std/marshal_impl.py
+++ b/pypy/objspace/std/marshal_impl.py
@@ -282,9 +282,9 @@
 
 def unmarshal_stringref(space, u, tc):
     idx = u.get_int()
-    try:
+    if 0 <= idx < len(u.stringtable_w):
         return u.stringtable_w[idx]
-    except IndexError:
+    else:
         raise_exception(space, 'bad marshal data')
 register(TYPE_STRINGREF, unmarshal_stringref)
 
diff --git a/pypy/objspace/std/newformat.py b/pypy/objspace/std/newformat.py
--- a/pypy/objspace/std/newformat.py
+++ b/pypy/objspace/std/newformat.py
@@ -201,7 +201,7 @@
             if empty:
                 index = self.auto_numbering
                 self.auto_numbering += 1
-            if index == -1:
+            if index < 0:
                 kwarg = name[:i]
                 if self.is_unicode:
                     try:
@@ -216,9 +216,9 @@
                 except KeyError:
                     raise OperationError(space.w_KeyError, space.wrap(arg_key))
             else:
-                try:
+                if index < len(self.args):
                     w_arg = self.args[index]
-                except IndexError:
+                else:
                     w_msg = space.wrap("index out of range")
                     raise OperationError(space.w_IndexError, w_msg)
             return self._resolve_lookups(w_arg, name, i, end)
diff --git a/pypy/objspace/std/tupleobject.py b/pypy/objspace/std/tupleobject.py
--- a/pypy/objspace/std/tupleobject.py
+++ b/pypy/objspace/std/tupleobject.py
@@ -10,7 +10,7 @@
 from pypy.objspace.std.inttype import wrapint
 from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
 from pypy.objspace.std.stdtypedef import StdTypeDef
-from pypy.objspace.std.util import negate
+from pypy.objspace.std.util import negate, getuindex, ListIndexError
 from rpython.rlib import jit
 from rpython.rlib.debug import make_sure_not_resized
 from rpython.rlib.rarithmetic import intmask
@@ -283,10 +283,11 @@
 
     def getitem(self, space, index):
         try:
-            return self.wrappeditems[index]
-        except IndexError:
+            uindex = getuindex(self.wrappeditems, index)
+        except ListIndexError:
             raise OperationError(space.w_IndexError,
                                  space.wrap("tuple index out of range"))
+        return self.wrappeditems[index]
 
 
 def wraptuple(space, list_w):
diff --git a/pypy/objspace/std/util.py b/pypy/objspace/std/util.py
--- a/pypy/objspace/std/util.py
+++ b/pypy/objspace/std/util.py
@@ -1,3 +1,6 @@
+from rpython.rlib.rarithmetic import r_uint
+
+
 def negate(f):
     """Create a function which calls `f` and negates its result.  When the
     result is ``space.w_NotImplemented``, ``space.w_NotImplemented`` is
@@ -25,3 +28,20 @@
         where = length
     assert where >= 0
     return where
+
+
+class ListIndexError(Exception):
+    """A custom RPython class, raised by getitem() and similar methods
+    from listobject.py, and from getuindex() below."""
+
+def getuindex(lst, index):
+    ulength = r_uint(len(lst))
+    uindex = r_uint(index)
+    if uindex >= ulength:
+        # Failed, so either (-length <= index < 0), or we have to raise
+        # ListIndexError.  First add 'length' to get the final index, then
+        # check that we now have (0 <= index < length).
+        uindex += ulength
+        if uindex >= ulength:
+            raise ListIndexError
+    return uindex
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to