Author: Armin Rigo <ar...@tunes.org> Branch: flow-no-local-exception Changeset: r65870:608476b35886 Date: 2013-07-31 12:53 +0200 http://bitbucket.org/pypy/pypy/changeset/608476b35886/
Log: Adapt lists diff --git a/pypy/objspace/std/iterobject.py b/pypy/objspace/std/iterobject.py --- a/pypy/objspace/std/iterobject.py +++ b/pypy/objspace/std/iterobject.py @@ -81,7 +81,7 @@ """Sequence iterator specialized for lists.""" def descr_next(self, space): - from pypy.objspace.std.listobject import W_ListObject + from pypy.objspace.std.listobject import W_ListObject, ListIndexError w_seq = self.w_seq if w_seq is None: raise OperationError(space.w_StopIteration, space.w_None) @@ -89,7 +89,7 @@ index = self.index try: w_item = w_seq.getitem(index) - except IndexError: + except ListIndexError: self.w_seq = None raise OperationError(space.w_StopIteration, space.w_None) self.index = index + 1 @@ -108,9 +108,10 @@ if self.tupleitems is None: raise OperationError(space.w_StopIteration, space.w_None) index = self.index - try: + assert index >= 0 + if index < len(self.tupleitems): w_item = self.tupleitems[index] - except IndexError: + else: self.tupleitems = None self.w_seq = None raise OperationError(space.w_StopIteration, space.w_None) 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 @@ -29,6 +29,7 @@ from pypy.objspace.std.unicodeobject import W_UnicodeObject from pypy.objspace.std.util import get_positive_index, negate 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) @@ -37,6 +38,10 @@ __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 @@ -245,13 +250,13 @@ def getitem(self, index): """Returns the wrapped object that is found in the list at the given index. The index must be unwrapped. - May raise IndexError.""" + May raise ListIndexError.""" return self.strategy.getitem(self, index) def getslice(self, start, stop, step, length): """Returns a slice of the list defined by the arguments. Arguments must be normalized (i.e. using normalize_simple_slice or W_Slice.indices4). - May raise IndexError.""" + May raise ListIndexError.""" return self.strategy.getslice(self, start, stop, step, length) def getitems(self): @@ -309,7 +314,7 @@ def pop(self, index): """Pops an item from the list. Index must be normalized. - May raise IndexError.""" + May raise ListIndexError.""" return self.strategy.pop(self, index) def pop_end(self): @@ -318,7 +323,7 @@ def setitem(self, index, w_item): """Inserts a wrapped item at the given (unwrapped) index. - May raise IndexError.""" + May raise ListIndexError.""" self.strategy.setitem(self, index, w_item) def setslice(self, start, step, slicelength, sequence_w): @@ -491,7 +496,7 @@ try: index = space.getindex_w(w_index, space.w_IndexError, "list index") return self.getitem(index) - except IndexError: + except ListIndexError: raise OperationError(space.w_IndexError, space.wrap("list index out of range")) @@ -519,7 +524,7 @@ idx = space.getindex_w(w_index, space.w_IndexError, "list index") try: self.setitem(idx, w_any) - except IndexError: + except ListIndexError: raise OperationError(space.w_IndexError, space.wrap("list index out of range")) @@ -546,7 +551,7 @@ idx += self.length() try: self.pop(idx) - except IndexError: + except ListIndexError: raise OperationError(space.w_IndexError, space.wrap("list index out of range")) @@ -597,7 +602,7 @@ index += length try: return self.pop(index) - except IndexError: + except ListIndexError: raise OperationError(space.w_IndexError, space.wrap("pop index out of range")) @@ -865,7 +870,7 @@ return 0 def getitem(self, w_list, index): - raise IndexError + raise ListIndexError def getslice(self, w_list, start, stop, step, length): # will never be called because the empty list case is already caught in @@ -913,10 +918,10 @@ def pop(self, w_list, index): # will not be called because IndexError was already raised in # list_pop__List_ANY - raise IndexError + raise ListIndexError def setitem(self, w_list, index, w_item): - raise IndexError + raise ListIndexError def setslice(self, w_list, start, step, slicelength, w_other): strategy = w_other.strategy @@ -1052,9 +1057,9 @@ if i < 0: i += length if i < 0: - raise IndexError + raise ListIndexError elif i >= length: - raise IndexError + raise ListIndexError return start + i * step def getitems_int(self, w_list): @@ -1235,13 +1240,21 @@ 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) - try: - r = l[index] - except IndexError: # make RPython raise the exception - raise - return self.wrap(r) + uindex = self._getidx(l, index) + return self.wrap(l[uindex]) @jit.look_inside_iff(lambda self, w_list: jit.loop_unrolling_heuristic(w_list, w_list.length(), @@ -1276,11 +1289,10 @@ subitems_w = [self._none_value] * length l = self.unerase(w_list.lstorage) for i in range(length): - try: - subitems_w[i] = l[start] - start += step - except IndexError: - raise + # I believe that the following 'l[start]' cannot raise + # an IndexError + subitems_w[i] = l[start] + start += step storage = self.erase(subitems_w) return W_ListObject.from_storage_and_strategy( self.space, storage, self) @@ -1319,10 +1331,8 @@ l = self.unerase(w_list.lstorage) if self.is_correct_type(w_item): - try: - l[index] = self.unwrap(w_item) - except IndexError: - raise + uindex = self._getidx(l, index) + l[uindex] = self.unwrap(w_item) return w_list.switch_to_object_strategy() @@ -1432,15 +1442,8 @@ def pop(self, w_list, index): l = self.unerase(w_list.lstorage) - # not sure if RPython raises IndexError on pop - # so check again here - if index < 0: - raise IndexError - try: - item = l.pop(index) - except IndexError: - raise - + uindex = self._getidx(l, index) + item = l.pop(uindex) w_item = self.wrap(item) return w_item _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit