[pypy-svn] r58921 - in pypy/branch/2.5-merge/pypy: interpreter objspace objspace/std objspace/std/test

arigo at codespeak.net arigo at codespeak.net
Fri Oct 10 18:26:05 CEST 2008


Author: arigo
Date: Fri Oct 10 18:26:04 2008
New Revision: 58921

Modified:
   pypy/branch/2.5-merge/pypy/interpreter/baseobjspace.py
   pypy/branch/2.5-merge/pypy/objspace/descroperation.py
   pypy/branch/2.5-merge/pypy/objspace/reflective.py
   pypy/branch/2.5-merge/pypy/objspace/std/builtinshortcut.py
   pypy/branch/2.5-merge/pypy/objspace/std/listobject.py
   pypy/branch/2.5-merge/pypy/objspace/std/objspace.py
   pypy/branch/2.5-merge/pypy/objspace/std/test/test_builtinshortcut.py
   pypy/branch/2.5-merge/pypy/objspace/std/test/test_listmultiobject.py
   pypy/branch/2.5-merge/pypy/objspace/std/test/test_listobject.py
   pypy/branch/2.5-merge/pypy/objspace/thunk.py
Log:
Revert r58914 and r58919, moving it to a branch.


Modified: pypy/branch/2.5-merge/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/branch/2.5-merge/pypy/interpreter/baseobjspace.py	(original)
+++ pypy/branch/2.5-merge/pypy/interpreter/baseobjspace.py	Fri Oct 10 18:26:04 2008
@@ -588,6 +588,17 @@
         w_s = self.interned_strings[s] = self.wrap(s)
         return w_s
 
+    # support for the deprecated __getslice__, __setslice__, __delslice__
+    def getslice(self, w_obj, w_start, w_stop):
+        w_slice = self.newslice(w_start, w_stop, self.w_None)
+        return self.getitem(w_obj, w_slice)
+    def setslice(self, w_obj, w_start, w_stop, w_sequence):
+        w_slice = self.newslice(w_start, w_stop, self.w_None)
+        self.setitem(w_obj, w_slice, w_sequence)
+    def delslice(self, w_obj, w_start, w_stop):
+        w_slice = self.newslice(w_start, w_stop, self.w_None)
+        self.delitem(w_obj, w_slice)
+
     def interpclass_w(space, w_obj):
         """
          If w_obj is a wrapped internal interpreter class instance unwrap to it,
@@ -1021,9 +1032,6 @@
     ('getitem',         'getitem',   2, ['__getitem__']),
     ('setitem',         'setitem',   3, ['__setitem__']),
     ('delitem',         'delitem',   2, ['__delitem__']),
-    ('getslice',        'getslice',  3, ['__getslice__']),
-    ('setslice',        'setslice',  4, ['__setslice__']),
-    ('delslice',        'delslice',  3, ['__delslice__']),
     ('pos',             'pos',       1, ['__pos__']),
     ('neg',             'neg',       1, ['__neg__']),
     ('nonzero',         'truth',     1, ['__nonzero__']),

Modified: pypy/branch/2.5-merge/pypy/objspace/descroperation.py
==============================================================================
--- pypy/branch/2.5-merge/pypy/objspace/descroperation.py	(original)
+++ pypy/branch/2.5-merge/pypy/objspace/descroperation.py	Fri Oct 10 18:26:04 2008
@@ -228,30 +228,6 @@
                    space.wrap("cannot delete items from object"))
         return space.get_and_call_function(w_descr, w_obj, w_key)
 
-    def getslice(space, w_obj, w_start, w_stop):
-        w_descr = space.lookup(w_obj, '__getslice__')
-        if w_descr is None:
-            w_slice = space.newslice(w_start, w_stop, space.w_None)
-            return space.getitem(w_obj, w_slice)
-        w_start, w_stop = old_slice_range(space, w_obj, w_start, w_stop)
-        return space.get_and_call_function(w_descr, w_obj, w_start, w_stop)
-
-    def setslice(space, w_obj, w_start, w_stop, w_sequence):
-        w_descr = space.lookup(w_obj, '__setslice__')
-        if w_descr is None:
-            w_slice = space.newslice(w_start, w_stop, space.w_None)
-            return space.setitem(w_obj, w_slice, w_sequence)
-        w_start, w_stop = old_slice_range(space, w_obj, w_start, w_stop)
-        return space.get_and_call_function(w_descr, w_obj, w_start, w_stop, w_sequence)
-
-    def delslice(space, w_obj, w_start, w_stop):
-        w_descr = space.lookup(w_obj, '__delslice__')
-        if w_descr is None:
-            w_slice = space.newslice(w_start, w_stop, space.w_None)
-            return space.delitem(w_obj, w_slice)
-        w_start, w_stop = old_slice_range(space, w_obj, w_start, w_stop)
-        return space.get_and_call_function(w_descr, w_obj, w_start, w_stop)
-
     def pow(space, w_obj1, w_obj2, w_obj3):
         w_typ1 = space.type(w_obj1)
         w_typ2 = space.type(w_obj2)
@@ -477,35 +453,6 @@
     return (space.lookup(w_obj, '__int__') is not None or
             space.lookup(w_obj, '__float__') is not None)
 
-
-
-# what is the maximum value slices can get on CPython?
-# we need to stick to that value, because fake.py etc.
-class Temp:
-    def __getslice__(self, i, j):
-        return j
-slice_max = Temp()[:]
-del Temp
-
-def old_slice_range(space, w_obj, w_start, w_stop):
-    """Only for backward compatibility for __getslice__()&co methods."""
-    if space.is_w(w_start, space.w_None):
-        w_start = space.wrap(0)
-    else:
-        w_start = space.wrap(space.getindex_w(w_start, None))
-        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)
-    else:
-        w_stop = space.wrap(space.getindex_w(w_stop, None))
-        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
-
 # regular methods def helpers
 
 def _make_binop_impl(symbol, specialnames):
@@ -702,3 +649,5 @@
                            'ord', 'unichr', 'unicode']:
             raise Exception, "missing def for operation %s" % _name
             
+            
+

Modified: pypy/branch/2.5-merge/pypy/objspace/reflective.py
==============================================================================
--- pypy/branch/2.5-merge/pypy/objspace/reflective.py	(original)
+++ pypy/branch/2.5-merge/pypy/objspace/reflective.py	Fri Oct 10 18:26:04 2008
@@ -89,14 +89,6 @@
                     return parentfn(w_arg1, w_arg2, w_arg3)
                 finally:
                     reset_reflective_space(space, w_old_reflectivespace)
-        elif args == 4:
-            def func(self, space, w_arg1, w_arg2, w_arg3, w_arg4):
-                w_old_reflectivespace = get_reflective_space(space)
-                set_reflectivespace(space, self.w_reflectivespace)
-                try:
-                    return parentfn(w_arg1, w_arg2, w_arg3, w_arg4)
-                finally:
-                    reset_reflective_space(space, w_old_reflectivespace)
         else:
             raise NotImplementedError
         unwrap_spec = ["self", ObjSpace] + [W_Root] * args

Modified: pypy/branch/2.5-merge/pypy/objspace/std/builtinshortcut.py
==============================================================================
--- pypy/branch/2.5-merge/pypy/objspace/std/builtinshortcut.py	(original)
+++ pypy/branch/2.5-merge/pypy/objspace/std/builtinshortcut.py	Fri Oct 10 18:26:04 2008
@@ -32,16 +32,10 @@
 KNOWN_MISSING = ['getattr',   # mostly non-builtins or optimized by CALL_METHOD
                  'setattr', 'delattr', 'userdel',  # mostly for non-builtins
                  'get', 'set', 'delete',   # uncommon (except on functions)
-                 'getslice', 'setslice', 'delslice',  # see below
-                 'delitem',                       # rare stuff?
-                 'abs', 'hex', 'oct',             # rare stuff?
+                 'delitem', 'abs', 'hex', 'oct',  # rare stuff?
                  'pos', 'divmod', 'cmp',          # rare stuff?
                  'float', 'long', 'coerce',       # rare stuff?
                  ]
-# We cannot support {get,set,del}slice right now because
-# DescrOperation.{get,set,del}slice do a bit more work than just call
-# the special methods: they call old_slice_range().  See e.g.
-# test_builtinshortcut.AppTestString.
 
 for _name, _, _, _specialmethods in ObjSpace.MethodTable:
     if _specialmethods:

Modified: pypy/branch/2.5-merge/pypy/objspace/std/listobject.py
==============================================================================
--- pypy/branch/2.5-merge/pypy/objspace/std/listobject.py	(original)
+++ pypy/branch/2.5-merge/pypy/objspace/std/listobject.py	Fri Oct 10 18:26:04 2008
@@ -80,30 +80,6 @@
         start += step
     return w_res
 
-def normalize_slice(space, w_list, w_start, w_stop):
-    start = space.int_w(w_start)
-    stop = space.int_w(w_stop)
-    length = len(w_list.wrappeditems)
-    if start < 0:
-        start = 0
-    if stop > length:
-        stop = length
-    if stop < start:
-        stop = start
-    return start, stop
-
-def getslice__List_ANY_ANY(space, w_list, w_start, w_stop):
-    start, stop = normalize_slice(space, w_list, w_start, w_stop)
-    return W_ListObject(w_list.wrappeditems[start:stop])
-
-def setslice__List_ANY_ANY_ANY(space, w_list, w_start, w_stop, w_sequence):
-    start, stop = normalize_slice(space, w_list, w_start, w_stop)
-    _setitem_slice_helper(space, w_list, start, 1, stop-start, w_sequence)
-
-def delslice__List_ANY_ANY(space, w_list, w_start, w_stop):
-    start, stop = normalize_slice(space, w_list, w_start, w_stop)
-    _delitem_slice_helper(space, w_list, start, 1, stop-start)
-
 def contains__List_ANY(space, w_list, w_obj):
     # needs to be safe against eq_w() mutating the w_list behind our back
     i = 0
@@ -214,35 +190,38 @@
                              space.wrap("list deletion index out of range"))
     return space.w_None
 
-
 def delitem__List_Slice(space, w_list, w_slice):
     start, stop, step, slicelength = w_slice.indices4(space,
                                                       len(w_list.wrappeditems))
-    _delitem_slice_helper(space, w_list, start, step, slicelength)
 
-def _delitem_slice_helper(space, w_list, start, step, slicelength):
     if slicelength==0:
         return
 
     if step < 0:
         start = start + step * (slicelength-1)
         step = -step
+        # stop is invalid
         
     if step == 1:
-        assert start >= 0
-        assert slicelength >= 0
-        del w_list.wrappeditems[start:start+slicelength]
+        _del_slice(w_list, start, start+slicelength)
     else:
         items = w_list.wrappeditems
         n = len(items)
+
+        recycle = [None] * slicelength
         i = start
 
+        # keep a reference to the objects to be removed,
+        # preventing side effects during destruction
+        recycle[0] = items[i]
+
         for discard in range(1, slicelength):
             j = i+1
             i += step
             while j < i:
                 items[j-discard] = items[j]
                 j += 1
+            recycle[discard] = items[i]
 
         j = i+1
         while j < n:
@@ -250,7 +229,13 @@
             j += 1
         start = n - slicelength
         assert start >= 0 # annotator hint
+        # XXX allow negative indices in rlist
         del items[start:]
+        # now we can destruct recycle safely, regardless of
+        # side-effects to the list
+        del recycle[:]
+
+    return space.w_None
 
 def setitem__List_ANY_ANY(space, w_list, w_index, w_any):
     idx = get_list_index(space, w_index)
@@ -261,25 +246,23 @@
                              space.wrap("list index out of range"))
     return space.w_None
 
+def setitem__List_Slice_List(space, w_list, w_slice, w_list2):
+    l = w_list2.wrappeditems
+    return _setitem_slice_helper(space, w_list, w_slice, l, len(l))
+
 def setitem__List_Slice_ANY(space, w_list, w_slice, w_iterable):
+    l = space.unpackiterable(w_iterable)
+    return _setitem_slice_helper(space, w_list, w_slice, l, len(l))
+
+def _setitem_slice_helper(space, w_list, w_slice, sequence2, len2):
     oldsize = len(w_list.wrappeditems)
     start, stop, step, slicelength = w_slice.indices4(space, oldsize)
-    _setitem_slice_helper(space, w_list, start, step, slicelength, w_iterable)
-
-def _setitem_slice_helper(space, w_list, start, step, slicelength, w_iterable):
-    if isinstance(w_iterable, W_ListObject):
-        sequence2 = w_iterable.wrappeditems
-    else:
-        sequence2 = space.unpackiterable(w_iterable)
-
     assert slicelength >= 0
     items = w_list.wrappeditems
-    oldsize = len(items)
-    len2 = len(sequence2)
+
     if step == 1:  # Support list resizing for non-extended slices
-        delta = slicelength - len2
-        if delta < 0:
-            delta = -delta
+        delta = len2 - slicelength
+        if delta >= 0:
             newsize = oldsize + delta
             # XXX support this in rlist!
             items += [None] * delta
@@ -288,10 +271,9 @@
             while i >= lim:
                 items[i] = items[i-delta]
                 i -= 1
-        elif start >= 0:
-            del items[start:start+delta]
         else:
-            assert delta==0
+            # shrinking requires the careful memory management of _del_slice()
+            _del_slice(w_list, start, start-delta)
     elif len2 != slicelength:  # No resize for extended slices
         raise OperationError(space.w_ValueError, space.wrap("attempt to "
               "assign sequence of size %d to extended slice of size %d" %
@@ -308,13 +290,14 @@
                 items[start] = sequence2[i]
                 start -= step
                 i -= 1
-            return
+            return space.w_None
         else:
             # Make a shallow copy to more easily handle the reversal case
             sequence2 = list(sequence2)
     for i in range(len2):
         items[start] = sequence2[i]
         start += step
+    return space.w_None
 
 app = gateway.applevel("""
     def listrepr(currently_in_repr, l):
@@ -367,6 +350,26 @@
     w_list.wrappeditems += space.unpackiterable(w_any)
     return space.w_None
 
+def _del_slice(w_list, ilow, ihigh):
+    """ similar to the deletion part of list_ass_slice in CPython """
+    items = w_list.wrappeditems
+    n = len(items)
+    if ilow < 0:
+        ilow = 0
+    elif ilow > n:
+        ilow = n
+    if ihigh < ilow:
+        ihigh = ilow
+    elif ihigh > n:
+        ihigh = n
+    # keep a reference to the objects to be removed,
+    # preventing side effects during destruction
+    recycle = items[ilow:ihigh]
+    del items[ilow:ihigh]
+    # now we can destruct recycle safely, regardless of
+    # side-effects to the list
+    del recycle[:]
+
 # note that the default value will come back wrapped!!!
 def list_pop__List_ANY(space, w_list, w_idx=-1):
     items = w_list.wrappeditems

Modified: pypy/branch/2.5-merge/pypy/objspace/std/objspace.py
==============================================================================
--- pypy/branch/2.5-merge/pypy/objspace/std/objspace.py	(original)
+++ pypy/branch/2.5-merge/pypy/objspace/std/objspace.py	Fri Oct 10 18:26:04 2008
@@ -764,6 +764,33 @@
         else:
             return ObjSpace.call_method(self, w_obj, methname, *arg_w)
 
+    # support for the deprecated __getslice__, __setslice__, __delslice__
+
+    def getslice(self, w_obj, w_start, w_stop):
+        w_descr = self.lookup(w_obj, '__getslice__')
+        if w_descr is not None:
+            w_start, w_stop = old_slice_range(self, w_obj, w_start, w_stop)
+            return self.get_and_call_function(w_descr, w_obj, w_start, w_stop)
+        else:
+            return ObjSpace.getslice(self, w_obj, w_start, w_stop)
+
+    def setslice(self, w_obj, w_start, w_stop, w_sequence):
+        w_descr = self.lookup(w_obj, '__setslice__')
+        if w_descr is not None:
+            w_start, w_stop = old_slice_range(self, w_obj, w_start, w_stop)
+            self.get_and_call_function(w_descr, w_obj, w_start, w_stop,
+                                       w_sequence)
+        else:
+            ObjSpace.setslice(self, w_obj, w_start, w_stop, w_sequence)
+
+    def delslice(self, w_obj, w_start, w_stop):
+        w_descr = self.lookup(w_obj, '__delslice__')
+        if w_descr is not None:
+            w_start, w_stop = old_slice_range(self, w_obj, w_start, w_stop)
+            self.get_and_call_function(w_descr, w_obj, w_start, w_stop)
+        else:
+            ObjSpace.delslice(self, w_obj, w_start, w_stop)
+
     def raise_key_error(self, w_key):
         e = self.call_function(self.w_KeyError, w_key)
         raise OperationError(self.w_KeyError, e)
@@ -793,3 +820,32 @@
                 del mm
 
         pow.extras['defaults'] = (None,)
+
+
+# what is the maximum value slices can get on CPython?
+# we need to stick to that value, because fake.py etc.
+class Temp:
+    def __getslice__(self, i, j):
+        return j
+slice_max = Temp()[:]
+del Temp
+
+
+def old_slice_range(space, w_obj, w_start, w_stop):
+    """Only for backward compatibility for __getslice__()&co methods."""
+    if space.is_w(w_start, space.w_None):
+        w_start = space.wrap(0)
+    else:
+        w_start = space.wrap(space.getindex_w(w_start, None))
+        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)
+    else:
+        w_stop = space.wrap(space.getindex_w(w_stop, None))
+        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/branch/2.5-merge/pypy/objspace/std/test/test_builtinshortcut.py
==============================================================================
--- pypy/branch/2.5-merge/pypy/objspace/std/test/test_builtinshortcut.py	(original)
+++ pypy/branch/2.5-merge/pypy/objspace/std/test/test_builtinshortcut.py	Fri Oct 10 18:26:04 2008
@@ -1,6 +1,5 @@
 from pypy.objspace.std.test import test_userobject
 from pypy.objspace.std.test import test_set
-from pypy.objspace.std.test import test_stringobject
 
 WITH_BUILTINSHORTCUT = {'objspace.std.builtinshortcut': True}
 
@@ -39,8 +38,3 @@
     def setup_class(cls):
         from pypy import conftest
         cls.space = conftest.gettestobjspace(**WITH_BUILTINSHORTCUT)
-
-class AppTestString(test_stringobject.AppTestStringObject):
-    def setup_class(cls):
-        from pypy import conftest
-        cls.space = conftest.gettestobjspace(**WITH_BUILTINSHORTCUT)

Modified: pypy/branch/2.5-merge/pypy/objspace/std/test/test_listmultiobject.py
==============================================================================
--- pypy/branch/2.5-merge/pypy/objspace/std/test/test_listmultiobject.py	(original)
+++ pypy/branch/2.5-merge/pypy/objspace/std/test/test_listmultiobject.py	Fri Oct 10 18:26:04 2008
@@ -39,15 +39,6 @@
         # These few here ^ would have failed before, but for good coverage,
         # all the list methods etc. should be tested also...
 
-    def test___getslice__(self):
-        skip("don't care for now")
-
-    def test___setslice__(self):
-        skip("don't care for now")
-        
-    def test___delslice__(self):
-        skip("don't care for now")
-
 class AppTest_ListMultiObject(BaseAppTest_ListMultiObject):
     def setup_class(cls):
         BaseAppTest_ListMultiObject.setup_class(cls)

Modified: pypy/branch/2.5-merge/pypy/objspace/std/test/test_listobject.py
==============================================================================
--- pypy/branch/2.5-merge/pypy/objspace/std/test/test_listobject.py	(original)
+++ pypy/branch/2.5-merge/pypy/objspace/std/test/test_listobject.py	Fri Oct 10 18:26:04 2008
@@ -754,18 +754,3 @@
             A()
             while lst:
                 keepalive.append(lst[:])
-
-    def test___getslice__(self):
-        l = [1,2,3,4]
-        res = l.__getslice__(0, 2)
-        assert res == [1, 2]
-
-    def test___setslice__(self):
-        l = [1,2,3,4]
-        l.__setslice__(0, 2, [5, 6])
-        assert l == [5, 6, 3, 4]
-
-    def test___delslice__(self):
-        l = [1,2,3,4]
-        l.__delslice__(0, 2)
-        assert l == [3, 4]

Modified: pypy/branch/2.5-merge/pypy/objspace/thunk.py
==============================================================================
--- pypy/branch/2.5-merge/pypy/objspace/thunk.py	(original)
+++ pypy/branch/2.5-merge/pypy/objspace/thunk.py	Fri Oct 10 18:26:04 2008
@@ -193,13 +193,6 @@
             w2 = force(space, w2)
             w3 = force(space, w3)
             return parentfn(w1, w2, w3, *extra)
-    elif nb_args == 4:
-        def proxy(w1, w2, w3, w4, *extra):
-            w1 = force(space, w1)
-            w2 = force(space, w2)
-            w3 = force(space, w3)
-            w4 = force(space, w4)
-            return parentfn(w1, w2, w3, w4, *extra)
     else:
         raise NotImplementedError("operation %r has arity %d" %
                                   (opname, nb_args))



More information about the Pypy-commit mailing list