[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