Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r48743:122e57eb1d74 Date: 2011-11-04 11:48 +0100 http://bitbucket.org/pypy/pypy/changeset/122e57eb1d74/
Log: merge heads 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 @@ -283,17 +283,9 @@ return space.wrap(''.join(w_bytearray.data)) def _convert_idx_params(space, w_self, w_start, w_stop): - start = slicetype.eval_slice_index(space, w_start) - stop = slicetype.eval_slice_index(space, w_stop) length = len(w_self.data) - if start < 0: - start += length - if start < 0: - start = 0 - if stop < 0: - stop += length - if stop < 0: - stop = 0 + start, stop = slicetype.unwrap_start_stop( + space, length, w_start, w_stop, False) return start, stop, length def str_count__Bytearray_Int_ANY_ANY(space, w_bytearray, w_char, w_start, w_stop): 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 @@ -419,8 +419,8 @@ # needs to be safe against eq_w() mutating the w_list behind our back items = w_list.wrappeditems size = len(items) - i = slicetype.adapt_bound(space, size, w_start) - stop = slicetype.adapt_bound(space, size, w_stop) + i, stop = slicetype.unwrap_start_stop( + space, size, w_start, w_stop, True) while i < stop and i < len(items): if space.eq_w(items[i], w_any): return space.wrap(i) diff --git a/pypy/objspace/std/ropeobject.py b/pypy/objspace/std/ropeobject.py --- a/pypy/objspace/std/ropeobject.py +++ b/pypy/objspace/std/ropeobject.py @@ -357,16 +357,8 @@ self = w_self._node sub = w_sub._node - if space.is_w(w_start, space.w_None): - w_start = space.wrap(0) - if space.is_w(w_end, space.w_None): - w_end = space.len(w_self) - if upper_bound: - start = slicetype.adapt_bound(space, self.length(), w_start) - end = slicetype.adapt_bound(space, self.length(), w_end) - else: - start = slicetype.adapt_lower_bound(space, self.length(), w_start) - end = slicetype.adapt_lower_bound(space, self.length(), w_end) + start, end = slicetype.unwrap_start_stop( + space, self.length(), w_start, w_end, upper_bound) return (self, sub, start, end) _convert_idx_params._annspecialcase_ = 'specialize:arg(5)' diff --git a/pypy/objspace/std/sliceobject.py b/pypy/objspace/std/sliceobject.py --- a/pypy/objspace/std/sliceobject.py +++ b/pypy/objspace/std/sliceobject.py @@ -4,7 +4,7 @@ from pypy.interpreter import gateway from pypy.objspace.std.model import registerimplementation, W_Object from pypy.objspace.std.register_all import register_all -from pypy.objspace.std.slicetype import eval_slice_index +from pypy.objspace.std.slicetype import _eval_slice_index class W_SliceObject(W_Object): from pypy.objspace.std.slicetype import slice_typedef as typedef @@ -25,7 +25,7 @@ if space.is_w(w_slice.w_step, space.w_None): step = 1 else: - step = eval_slice_index(space, w_slice.w_step) + step = _eval_slice_index(space, w_slice.w_step) if step == 0: raise OperationError(space.w_ValueError, space.wrap("slice step cannot be zero")) @@ -35,7 +35,7 @@ else: start = 0 else: - start = eval_slice_index(space, w_slice.w_start) + start = _eval_slice_index(space, w_slice.w_start) if start < 0: start += length if start < 0: @@ -54,7 +54,7 @@ else: stop = length else: - stop = eval_slice_index(space, w_slice.w_stop) + stop = _eval_slice_index(space, w_slice.w_stop) if stop < 0: stop += length if stop < 0: diff --git a/pypy/objspace/std/slicetype.py b/pypy/objspace/std/slicetype.py --- a/pypy/objspace/std/slicetype.py +++ b/pypy/objspace/std/slicetype.py @@ -3,6 +3,7 @@ from pypy.objspace.std.stdtypedef import StdTypeDef, SMM from pypy.objspace.std.register_all import register_all from pypy.interpreter.error import OperationError +from pypy.rlib.objectmodel import specialize # indices multimehtod slice_indices = SMM('indices', 2, @@ -14,7 +15,9 @@ ' normal slices.') # utility functions -def eval_slice_index(space, w_int): +def _eval_slice_index(space, w_int): + # note that it is the *callers* responsibility to check for w_None + # otherwise you can get funny error messages try: return space.getindex_w(w_int, None) # clamp if long integer too large except OperationError, err: @@ -25,7 +28,7 @@ "None or have an __index__ method")) def adapt_lower_bound(space, size, w_index): - index = eval_slice_index(space, w_index) + index = _eval_slice_index(space, w_index) if index < 0: index = index + size if index < 0: @@ -34,16 +37,29 @@ return index def adapt_bound(space, size, w_index): - index = eval_slice_index(space, w_index) - if index < 0: - index = index + size - if index < 0: - index = 0 + index = adapt_lower_bound(space, size, w_index) if index > size: index = size assert index >= 0 return index +@specialize.arg(4) +def unwrap_start_stop(space, size, w_start, w_end, upper_bound=False): + if space.is_w(w_start, space.w_None): + start = 0 + elif upper_bound: + start = adapt_bound(space, size, w_start) + else: + start = adapt_lower_bound(space, size, w_start) + + if space.is_w(w_end, space.w_None): + end = size + elif upper_bound: + end = adapt_bound(space, size, w_end) + else: + end = adapt_lower_bound(space, size, w_end) + return start, end + register_all(vars(), globals()) # ____________________________________________________________ diff --git a/pypy/objspace/std/smalltupleobject.py b/pypy/objspace/std/smalltupleobject.py --- a/pypy/objspace/std/smalltupleobject.py +++ b/pypy/objspace/std/smalltupleobject.py @@ -68,10 +68,10 @@ raise IndexError def eq(self, space, w_other): - if self.length() != w_other.length(): + if n != w_other.length(): return space.w_False for i in iter_n: - item1 = self.getitem(i) + item1 = getattr(self,'w_value%s' % i) item2 = w_other.getitem(i) if not space.eq_w(item1, item2): return space.w_False @@ -80,9 +80,9 @@ def hash(self, space): mult = 1000003 x = 0x345678 - z = self.length() + z = n for i in iter_n: - w_item = self.getitem(i) + w_item = getattr(self, 'w_value%s' % i) y = space.int_w(space.hash(w_item)) x = (x ^ y) * mult z -= 1 diff --git a/pypy/objspace/std/stringobject.py b/pypy/objspace/std/stringobject.py --- a/pypy/objspace/std/stringobject.py +++ b/pypy/objspace/std/stringobject.py @@ -4,7 +4,7 @@ from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter import gateway from pypy.rlib.rarithmetic import ovfcheck -from pypy.rlib.objectmodel import we_are_translated, compute_hash +from pypy.rlib.objectmodel import we_are_translated, compute_hash, specialize from pypy.objspace.std.inttype import wrapint from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice from pypy.objspace.std import slicetype, newformat @@ -47,6 +47,7 @@ W_StringObject.PREBUILT = [W_StringObject(chr(i)) for i in range(256)] del i +@specialize.arg(2) def _is_generic(space, w_self, fun): v = w_self._value if len(v) == 0: @@ -56,14 +57,13 @@ return space.newbool(fun(c)) else: return _is_generic_loop(space, v, fun) -_is_generic._annspecialcase_ = "specialize:arg(2)" +@specialize.arg(2) def _is_generic_loop(space, v, fun): for idx in range(len(v)): if not fun(v[idx]): return space.w_False return space.w_True -_is_generic_loop._annspecialcase_ = "specialize:arg(2)" def _upper(ch): if ch.islower(): @@ -420,22 +420,14 @@ return space.wrap(u_self) -def _convert_idx_params(space, w_self, w_sub, w_start, w_end, upper_bound=False): +@specialize.arg(4) +def _convert_idx_params(space, w_self, w_start, w_end, upper_bound=False): self = w_self._value - sub = w_sub._value + lenself = len(self) - if space.is_w(w_start, space.w_None): - w_start = space.wrap(0) - if space.is_w(w_end, space.w_None): - w_end = space.len(w_self) - if upper_bound: - start = slicetype.adapt_bound(space, len(self), w_start) - end = slicetype.adapt_bound(space, len(self), w_end) - else: - start = slicetype.adapt_lower_bound(space, len(self), w_start) - end = slicetype.adapt_lower_bound(space, len(self), w_end) - return (self, sub, start, end) -_convert_idx_params._annspecialcase_ = 'specialize:arg(5)' + start, end = slicetype.unwrap_start_stop( + space, lenself, w_start, w_end, upper_bound=upper_bound) + return (self, start, end) def contains__String_String(space, w_self, w_sub): self = w_self._value @@ -443,13 +435,13 @@ return space.newbool(self.find(sub) >= 0) def str_find__String_String_ANY_ANY(space, w_self, w_sub, w_start, w_end): - (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end) - res = self.find(sub, start, end) + (self, start, end) = _convert_idx_params(space, w_self, w_start, w_end) + res = self.find(w_sub._value, start, end) return space.wrap(res) def str_rfind__String_String_ANY_ANY(space, w_self, w_sub, w_start, w_end): - (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end) - res = self.rfind(sub, start, end) + (self, start, end) = _convert_idx_params(space, w_self, w_start, w_end) + res = self.rfind(w_sub._value, start, end) return space.wrap(res) def str_partition__String_String(space, w_self, w_sub): @@ -483,8 +475,8 @@ def str_index__String_String_ANY_ANY(space, w_self, w_sub, w_start, w_end): - (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end) - res = self.find(sub, start, end) + (self, start, end) = _convert_idx_params(space, w_self, w_start, w_end) + res = self.find(w_sub._value, start, end) if res < 0: raise OperationError(space.w_ValueError, space.wrap("substring not found in string.index")) @@ -493,8 +485,8 @@ def str_rindex__String_String_ANY_ANY(space, w_self, w_sub, w_start, w_end): - (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end) - res = self.rfind(sub, start, end) + (self, start, end) = _convert_idx_params(space, w_self, w_start, w_end) + res = self.rfind(w_sub._value, start, end) if res < 0: raise OperationError(space.w_ValueError, space.wrap("substring not found in string.rindex")) @@ -636,20 +628,17 @@ return wrapstr(space, u_centered) def str_count__String_String_ANY_ANY(space, w_self, w_arg, w_start, w_end): - u_self, u_arg, u_start, u_end = _convert_idx_params(space, w_self, w_arg, - w_start, w_end) - return wrapint(space, u_self.count(u_arg, u_start, u_end)) + u_self, u_start, u_end = _convert_idx_params(space, w_self, w_start, w_end) + return wrapint(space, u_self.count(w_arg._value, u_start, u_end)) def str_endswith__String_String_ANY_ANY(space, w_self, w_suffix, w_start, w_end): - (u_self, suffix, start, end) = _convert_idx_params(space, w_self, - w_suffix, w_start, - w_end, True) - return space.newbool(stringendswith(u_self, suffix, start, end)) + (u_self, start, end) = _convert_idx_params(space, w_self, w_start, + w_end, True) + return space.newbool(stringendswith(u_self, w_suffix._value, start, end)) def str_endswith__String_Tuple_ANY_ANY(space, w_self, w_suffixes, w_start, w_end): - (u_self, _, start, end) = _convert_idx_params(space, w_self, - space.wrap(''), w_start, - w_end, True) + (u_self, start, end) = _convert_idx_params(space, w_self, w_start, + w_end, True) for w_suffix in space.fixedview(w_suffixes): if space.isinstance_w(w_suffix, space.w_unicode): w_u = space.call_function(space.w_unicode, w_self) @@ -661,14 +650,13 @@ return space.w_False def str_startswith__String_String_ANY_ANY(space, w_self, w_prefix, w_start, w_end): - (u_self, prefix, start, end) = _convert_idx_params(space, w_self, - w_prefix, w_start, - w_end, True) - return space.newbool(stringstartswith(u_self, prefix, start, end)) + (u_self, start, end) = _convert_idx_params(space, w_self, w_start, + w_end, True) + return space.newbool(stringstartswith(u_self, w_prefix._value, start, end)) def str_startswith__String_Tuple_ANY_ANY(space, w_self, w_prefixes, w_start, w_end): - (u_self, _, start, end) = _convert_idx_params(space, w_self, space.wrap(''), - w_start, w_end, True) + (u_self, start, end) = _convert_idx_params(space, w_self, + w_start, w_end, True) for w_prefix in space.fixedview(w_prefixes): if space.isinstance_w(w_prefix, space.w_unicode): w_u = space.call_function(space.w_unicode, w_self) diff --git a/pypy/objspace/std/strsliceobject.py b/pypy/objspace/std/strsliceobject.py --- a/pypy/objspace/std/strsliceobject.py +++ b/pypy/objspace/std/strsliceobject.py @@ -60,8 +60,8 @@ def _convert_idx_params(space, w_self, w_sub, w_start, w_end): length = w_self.stop - w_self.start sub = w_sub._value - start = slicetype.adapt_bound(space, length, w_start) - end = slicetype.adapt_bound(space, length, w_end) + start, end = slicetype.unwrap_start_stop( + space, length, w_start, w_end, True) assert start >= 0 assert end >= 0 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 @@ -2,11 +2,10 @@ from pypy.objspace.std.listobject import W_ListObject from pypy.interpreter.error import OperationError -from pypy.conftest import gettestobjspace +from pypy.conftest import gettestobjspace, option class TestW_ListObject(object): - def test_is_true(self): w = self.space.wrap w_list = W_ListObject([]) @@ -343,6 +342,13 @@ class AppTestW_ListObject(object): + def setup_class(cls): + import sys + on_cpython = (option.runappdirect and + not hasattr(sys, 'pypy_translation_info')) + + cls.w_on_cpython = cls.space.wrap(on_cpython) + def test_call_list(self): assert list('') == [] assert list('abc') == ['a', 'b', 'c'] @@ -616,6 +622,14 @@ assert c.index(0) == 0 raises(ValueError, c.index, 3) + def test_index_cpython_bug(self): + if self.on_cpython: + skip("cpython has a bug here") + c = list('hello world') + assert c.index('l', None, None) == 2 + assert c.index('l', 3, None) == 3 + assert c.index('l', None, 4) == 2 + def test_ass_slice(self): l = range(6) l[1:3] = 'abc' 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 @@ -167,17 +167,8 @@ return space.wrap(count) def tuple_index__Tuple_ANY_ANY_ANY(space, w_tuple, w_obj, w_start, w_stop): - start = slicetype.eval_slice_index(space, w_start) - stop = slicetype.eval_slice_index(space, w_stop) length = len(w_tuple.wrappeditems) - if start < 0: - start += length - if start < 0: - start = 0 - if stop < 0: - stop += length - if stop < 0: - stop = 0 + start, stop = slicetype.unwrap_start_stop(space, length, w_start, w_stop) for i in range(start, min(stop, length)): w_item = w_tuple.wrappeditems[i] if space.eq_w(w_item, w_obj): diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py --- a/pypy/objspace/std/unicodeobject.py +++ b/pypy/objspace/std/unicodeobject.py @@ -479,18 +479,8 @@ assert isinstance(w_sub, W_UnicodeObject) self = w_self._value sub = w_sub._value - - if space.is_w(w_start, space.w_None): - w_start = space.wrap(0) - if space.is_w(w_end, space.w_None): - w_end = space.len(w_self) - - if upper_bound: - start = slicetype.adapt_bound(space, len(self), w_start) - end = slicetype.adapt_bound(space, len(self), w_end) - else: - start = slicetype.adapt_lower_bound(space, len(self), w_start) - end = slicetype.adapt_lower_bound(space, len(self), w_end) + start, end = slicetype.unwrap_start_stop( + space, len(self), w_start, w_end, upper_bound) return (self, sub, start, end) _convert_idx_params._annspecialcase_ = 'specialize:arg(5)' _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit