[pypy-svn] r39971 - in pypy/dist/pypy: interpreter objspace/std objspace/std/test

gbrandl at codespeak.net gbrandl at codespeak.net
Tue Mar 6 00:21:16 CET 2007


Author: gbrandl
Date: Tue Mar  6 00:21:14 2007
New Revision: 39971

Modified:
   pypy/dist/pypy/interpreter/baseobjspace.py
   pypy/dist/pypy/objspace/std/listmultiobject.py
   pypy/dist/pypy/objspace/std/listobject.py
   pypy/dist/pypy/objspace/std/objspace.py
   pypy/dist/pypy/objspace/std/slicetype.py
   pypy/dist/pypy/objspace/std/stringobject.py
   pypy/dist/pypy/objspace/std/strsliceobject.py
   pypy/dist/pypy/objspace/std/test/test_index.py
Log:
Some string/list methods use __index__ for their "slice" arguments too.
Also, make _Eval_SliceIndex act more like its CPython counterpart.


Modified: pypy/dist/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/dist/pypy/interpreter/baseobjspace.py	(original)
+++ pypy/dist/pypy/interpreter/baseobjspace.py	Tue Mar  6 00:21:14 2007
@@ -786,6 +786,10 @@
         return start, stop, step
 
     def getindex_w(self, w_obj, w_exception=None):
+        # shortcut for int objects
+        if self.is_w(self.type(w_obj), self.w_int):
+            return self.int_w(w_obj)
+
         w_index = self.index(w_obj)
         try:
             index = self.int_w(w_index)

Modified: pypy/dist/pypy/objspace/std/listmultiobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/listmultiobject.py	(original)
+++ pypy/dist/pypy/objspace/std/listmultiobject.py	Tue Mar  6 00:21:14 2007
@@ -1218,10 +1218,8 @@
 def list_index__ListMulti_ANY_ANY_ANY(space, w_list, w_any, w_start, w_stop):
     # needs to be safe against eq_w() mutating the w_list behind our back
     length = w_list.implementation.length()
-    w_start = slicetype.adapt_bound(space, w_start, space.wrap(length))
-    w_stop = slicetype.adapt_bound(space, w_stop, space.wrap(length))
-    i = space.int_w(w_start)
-    stop = space.int_w(w_stop)
+    i = slicetype.adapt_bound(space, length, w_start)
+    stop = slicetype.adapt_bound(space, length, w_stop)
     while i < stop and i < w_list.implementation.length():
         if space.eq_w(w_list.implementation.getitem(i), w_any):
             return space.wrap(i)

Modified: pypy/dist/pypy/objspace/std/listobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/listobject.py	(original)
+++ pypy/dist/pypy/objspace/std/listobject.py	Tue Mar  6 00:21:14 2007
@@ -390,10 +390,8 @@
     # needs to be safe against eq_w() mutating the w_list behind our back
     items = w_list.wrappeditems
     size = len(items)
-    w_start = slicetype.adapt_bound(space, w_start, space.wrap(size))
-    w_stop = slicetype.adapt_bound(space, w_stop, space.wrap(size))
-    i = space.int_w(w_start)
-    stop = space.int_w(w_stop)
+    i = slicetype.adapt_bound(space, size, w_start)
+    stop = slicetype.adapt_bound(space, size, w_stop)
     while i < stop and i < len(items):
         if space.eq_w(items[i], w_any):
             return space.wrap(i)

Modified: pypy/dist/pypy/objspace/std/objspace.py
==============================================================================
--- pypy/dist/pypy/objspace/std/objspace.py	(original)
+++ pypy/dist/pypy/objspace/std/objspace.py	Tue Mar  6 00:21:14 2007
@@ -624,13 +624,17 @@
     """Only for backward compatibility for __getslice__()&co methods."""
     if space.is_w(w_start, space.w_None):
         w_start = space.wrap(0)
-    elif space.is_true(space.lt(w_start, space.wrap(0))):
-        w_start = space.add(w_start, space.len(w_obj))
-        # NB. the language ref is inconsistent with the new-style class
-        # behavior when w_obj doesn't implement __len__(), so we just
-        # ignore this case.
+    else:
+        w_start = space.wrap(space.getindex_w(w_start))
+        if space.is_true(space.lt(w_start, space.wrap(0))):
+            w_start = space.add(w_start, space.len(w_obj))
+            # NB. the language ref is inconsistent with the new-style class
+            # behavior when w_obj doesn't implement __len__(), so we just
+            # ignore this case.
     if space.is_w(w_stop, space.w_None):
         w_stop = space.wrap(slice_max)
-    elif space.is_true(space.lt(w_stop, space.wrap(0))):
-        w_stop = space.add(w_stop, space.len(w_obj))
+    else:
+        w_stop = space.wrap(space.getindex_w(w_stop))
+        if space.is_true(space.lt(w_stop, space.wrap(0))):
+            w_stop = space.add(w_stop, space.len(w_obj))
     return w_start, w_stop

Modified: pypy/dist/pypy/objspace/std/slicetype.py
==============================================================================
--- pypy/dist/pypy/objspace/std/slicetype.py	(original)
+++ pypy/dist/pypy/objspace/std/slicetype.py	Tue Mar  6 00:21:14 2007
@@ -15,32 +15,24 @@
 
 # utility functions
 def _Eval_SliceIndex(space, w_int):
-    return space.getindex_w(w_int) # clamp if long integer is too large
-    # This is done by getindex_w already.
-    #try:
-    #    x = space.getindex_w(w_int)
-    #except OperationError, e:
-    #    if not e.match(space, space.w_OverflowError):
-    #        raise
-    #    cmp = space.is_true(space.ge(w_int, space.wrap(0)))
-    #    if cmp:
-    #        x = sys.maxint
-    #    else:
-    #        x = -sys.maxint
-    #return x
-
-def adapt_bound(space, w_index, w_size):
-    if not (space.is_true(space.isinstance(w_index, space.w_int)) or
-            space.is_true(space.isinstance(w_index, space.w_long))):
+    try:
+        return space.getindex_w(w_int) # clamp if long integer is too large
+    except OperationError, err:
+        if not err.match(space, space.w_TypeError):
+            raise
         raise OperationError(space.w_TypeError,
-                             space.wrap("slice indices must be integers"))
-    if space.is_true(space.lt(w_index, space.wrap(0))):
-        w_index = space.add(w_index, w_size)
-        if space.is_true(space.lt(w_index, space.wrap(0))):
-            w_index = space.wrap(0)
-    if space.is_true(space.gt(w_index, w_size)):
-        w_index = w_size
-    return w_index
+                             space.wrap("slice indices must be integers or "
+                                        "None or have an __index__ method"))
+
+def adapt_bound(space, size, w_index):
+    index = _Eval_SliceIndex(space, w_index)
+    if index < 0:
+        index = index + size
+        if index < 0:
+            index = 0
+    if index > size:
+        index = size
+    return index
 
 register_all(vars(), globals())
 

Modified: pypy/dist/pypy/objspace/std/stringobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/stringobject.py	(original)
+++ pypy/dist/pypy/objspace/std/stringobject.py	Tue Mar  6 00:21:14 2007
@@ -377,11 +377,9 @@
 def _convert_idx_params(space, w_self, w_sub, w_start, w_end):
     self = w_self._value
     sub = w_sub._value
-    w_start = slicetype.adapt_bound(space, w_start, space.wrap(len(self)))
-    w_end = slicetype.adapt_bound(space, w_end, space.wrap(len(self)))
+    start = slicetype.adapt_bound(space, len(self), w_start)
+    end = slicetype.adapt_bound(space, len(self), w_end)
 
-    start = space.int_w(w_start)
-    end = space.int_w(w_end)
     assert start >= 0
     assert end >= 0
 
@@ -562,15 +560,8 @@
     return wrapstr(space, u_centered)
 
 def str_count__String_String_ANY_ANY(space, w_self, w_arg, w_start, w_end): 
-    u_self  = w_self._value
-    u_arg   = w_arg._value
-
-    w_start = slicetype.adapt_bound(space, w_start, space.wrap(len(u_self)))
-    w_end = slicetype.adapt_bound(space, w_end, space.wrap(len(u_self)))
-    u_start = space.int_w(w_start)
-    u_end = space.int_w(w_end)
-    assert u_start >= 0
-    assert u_end >= 0
+    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))
 
 def str_endswith__String_String_ANY_ANY(space, w_self, w_suffix, w_start, w_end):

Modified: pypy/dist/pypy/objspace/std/strsliceobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/strsliceobject.py	(original)
+++ pypy/dist/pypy/objspace/std/strsliceobject.py	Tue Mar  6 00:21:14 2007
@@ -55,11 +55,9 @@
 def _convert_idx_params(space, w_self, w_sub, w_start, w_end):
     length = w_self.stop - w_self.start
     sub = w_sub._value
-    w_start = slicetype.adapt_bound(space, w_start, space.wrap(length))
-    w_end = slicetype.adapt_bound(space, w_end, space.wrap(length))
+    start = slicetype.adapt_bound(space, length, w_start)
+    end = slicetype.adapt_bound(space, length, w_end)
 
-    start = space.int_w(w_start)
-    end = space.int_w(w_end)
     assert start >= 0
     assert end >= 0
 
@@ -67,7 +65,7 @@
 
 
 def str_find__StringSlice_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)
+    (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end)
     res = self.find(sub, start, end)
     if res >= 0:
         return space.wrap(res - w_self.start)

Modified: pypy/dist/pypy/objspace/std/test/test_index.py
==============================================================================
--- pypy/dist/pypy/objspace/std/test/test_index.py	(original)
+++ pypy/dist/pypy/objspace/std/test/test_index.py	Tue Mar  6 00:21:14 2007
@@ -51,6 +51,13 @@
         check_slc = slice(2, 2, 2)
         assert slc.indices(self.n) == check_slc.indices(2)
 
+    def test_in_methods(self):
+        self.o.ind = 5
+        self.n.ind = 10
+        s = "abcdefghijklmno"
+        assert s.find("a", self.o, self.n) == -1
+        assert s.find("f", self.o, self.n) == 5
+
     def test_wrappers(self):
         self.o.ind = 4
         self.n.ind = 5



More information about the Pypy-commit mailing list