[pypy-svn] r58930 - in pypy/branch/getslice/pypy: annotation annotation/test interpreter objspace objspace/flow objspace/std objspace/std/test rpython rpython/lltypesystem rpython/ootypesystem rpython/test translator
arigo at codespeak.net
arigo at codespeak.net
Fri Oct 10 19:38:46 CEST 2008
Author: arigo
Date: Fri Oct 10 19:38:43 2008
New Revision: 58930
Removed:
pypy/branch/getslice/pypy/rpython/lltypesystem/rslice.py
pypy/branch/getslice/pypy/rpython/ootypesystem/rslice.py
pypy/branch/getslice/pypy/rpython/rslice.py
Modified:
pypy/branch/getslice/pypy/annotation/annrpython.py
pypy/branch/getslice/pypy/annotation/binaryop.py
pypy/branch/getslice/pypy/annotation/bookkeeper.py
pypy/branch/getslice/pypy/annotation/builtin.py
pypy/branch/getslice/pypy/annotation/model.py
pypy/branch/getslice/pypy/annotation/test/test_annrpython.py
pypy/branch/getslice/pypy/annotation/unaryop.py
pypy/branch/getslice/pypy/interpreter/baseobjspace.py
pypy/branch/getslice/pypy/objspace/descroperation.py
pypy/branch/getslice/pypy/objspace/flow/objspace.py
pypy/branch/getslice/pypy/objspace/reflective.py
pypy/branch/getslice/pypy/objspace/std/builtinshortcut.py
pypy/branch/getslice/pypy/objspace/std/listobject.py
pypy/branch/getslice/pypy/objspace/std/objspace.py
pypy/branch/getslice/pypy/objspace/std/rangeobject.py
pypy/branch/getslice/pypy/objspace/std/ropeobject.py
pypy/branch/getslice/pypy/objspace/std/ropeunicodeobject.py
pypy/branch/getslice/pypy/objspace/std/sliceobject.py
pypy/branch/getslice/pypy/objspace/std/stringobject.py
pypy/branch/getslice/pypy/objspace/std/strsliceobject.py
pypy/branch/getslice/pypy/objspace/std/test/test_builtinshortcut.py
pypy/branch/getslice/pypy/objspace/std/test/test_listmultiobject.py
pypy/branch/getslice/pypy/objspace/std/test/test_listobject.py
pypy/branch/getslice/pypy/objspace/std/test/test_rangeobject.py
pypy/branch/getslice/pypy/objspace/std/test/test_stringobject.py
pypy/branch/getslice/pypy/objspace/std/test/test_strsliceobject.py
pypy/branch/getslice/pypy/objspace/std/test/test_tupleobject.py
pypy/branch/getslice/pypy/objspace/std/test/test_unicodeobject.py
pypy/branch/getslice/pypy/objspace/std/tupleobject.py
pypy/branch/getslice/pypy/objspace/std/unicodeobject.py
pypy/branch/getslice/pypy/objspace/thunk.py
pypy/branch/getslice/pypy/rpython/lltypesystem/rlist.py
pypy/branch/getslice/pypy/rpython/ootypesystem/rlist.py
pypy/branch/getslice/pypy/rpython/rlist.py
pypy/branch/getslice/pypy/rpython/rstr.py
pypy/branch/getslice/pypy/rpython/rtuple.py
pypy/branch/getslice/pypy/rpython/rtyper.py
pypy/branch/getslice/pypy/rpython/test/test_rlist.py
pypy/branch/getslice/pypy/translator/simplify.py
pypy/branch/getslice/pypy/translator/transform.py
Log:
(antocuni, arigo)
Probably in-progress.
Modified: pypy/branch/getslice/pypy/annotation/annrpython.py
==============================================================================
--- pypy/branch/getslice/pypy/annotation/annrpython.py (original)
+++ pypy/branch/getslice/pypy/annotation/annrpython.py Fri Oct 10 19:38:43 2008
@@ -760,10 +760,6 @@
def consider_op_newdict(self):
return self.bookkeeper.newdict()
- def consider_op_newslice(self, start, stop, step):
- self.bookkeeper.count('newslice', start, stop, step)
- return annmodel.SomeSlice(start, stop, step)
-
def _registeroperations(cls, model):
# All unary operations
Modified: pypy/branch/getslice/pypy/annotation/binaryop.py
==============================================================================
--- pypy/branch/getslice/pypy/annotation/binaryop.py (original)
+++ pypy/branch/getslice/pypy/annotation/binaryop.py Fri Oct 10 19:38:43 2008
@@ -10,7 +10,7 @@
from pypy.annotation.model import SomeUnicodeCodePoint
from pypy.annotation.model import SomeTuple, SomeImpossibleValue, s_ImpossibleValue
from pypy.annotation.model import SomeInstance, SomeBuiltin, SomeIterator
-from pypy.annotation.model import SomePBC, SomeSlice, SomeFloat, s_None
+from pypy.annotation.model import SomePBC, SomeFloat, s_None
from pypy.annotation.model import SomeExternalObject, SomeWeakRef
from pypy.annotation.model import SomeAddress, SomeTypedAddressAccess
from pypy.annotation.model import SomeSingleFloat
@@ -564,14 +564,6 @@
delitem.can_only_throw = _can_only_throw
-class __extend__(pairtype(SomeSlice, SomeSlice)):
-
- def union((slic1, slic2)):
- return SomeSlice(unioncheck(slic1.start, slic2.start),
- unioncheck(slic1.stop, slic2.stop),
- unioncheck(slic1.step, slic2.step))
-
-
class __extend__(pairtype(SomeTuple, SomeInteger)):
def getitem((tup1, int2)):
@@ -585,13 +577,6 @@
return unionof(*tup1.items)
getitem.can_only_throw = [IndexError]
-class __extend__(pairtype(SomeTuple, SomeSlice)):
-
- def getitem((tup, slic)):
- start, stop, step = slic.constant_indices()
- return SomeTuple(tup.items[start:stop:step])
- getitem.can_only_throw = []
-
class __extend__(pairtype(SomeList, SomeInteger)):
@@ -623,40 +608,6 @@
lst1.listdef.resize()
delitem.can_only_throw = [IndexError]
-def check_negative_slice(s_slice):
- if isinstance(s_slice.start, SomeInteger) and not s_slice.start.nonneg:
- raise TypeError("%s not proven to have non-negative start" % s_slice)
- if isinstance(s_slice.stop, SomeInteger) and not s_slice.stop.nonneg and\
- getattr(s_slice.stop, 'const', 0) != -1:
- raise TypeError("%s not proven to have non-negative stop" % s_slice)
-
-class __extend__(pairtype(SomeList, SomeSlice)):
-
- def getitem((lst, slic)):
- check_negative_slice(slic)
- return lst.listdef.offspring()
- getitem.can_only_throw = []
-
- def setitem((lst, slic), s_iterable):
- check_negative_slice(slic)
- # we need the same unifying effect as the extend() method for
- # the case lst1[x:y] = lst2.
- lst.method_extend(s_iterable)
- setitem.can_only_throw = []
-
- def delitem((lst1, slic)):
- check_negative_slice(slic)
- lst1.listdef.resize()
- delitem.can_only_throw = []
-
-class __extend__(pairtype(SomeString, SomeSlice),
- pairtype(SomeUnicodeString, SomeSlice)):
-
- def getitem((str1, slic)):
- check_negative_slice(slic)
- return str1.basestringclass()
- getitem.can_only_throw = []
-
class __extend__(pairtype(SomeString, SomeInteger)):
def getitem((str1, int2)):
Modified: pypy/branch/getslice/pypy/annotation/bookkeeper.py
==============================================================================
--- pypy/branch/getslice/pypy/annotation/bookkeeper.py (original)
+++ pypy/branch/getslice/pypy/annotation/bookkeeper.py Fri Oct 10 19:38:43 2008
@@ -68,9 +68,6 @@
def consider_generic(self, *args):
return tuple([self.typerepr(x) for x in args])
- def consider_newslice(self, s_start, s_stop, s_step):
- return ':'.join([self.indexrepr(s_start), self.indexrepr(s_stop), self.steprepr(s_step)])
-
def consider_list_list_eq(self, obj1, obj2):
return obj1, obj2
Modified: pypy/branch/getslice/pypy/annotation/builtin.py
==============================================================================
--- pypy/branch/getslice/pypy/annotation/builtin.py (original)
+++ pypy/branch/getslice/pypy/annotation/builtin.py Fri Oct 10 19:38:43 2008
@@ -4,7 +4,7 @@
import sys
from pypy.annotation.model import SomeInteger, SomeObject, SomeChar, SomeBool
-from pypy.annotation.model import SomeString, SomeTuple, SomeSlice, s_Bool
+from pypy.annotation.model import SomeString, SomeTuple, s_Bool
from pypy.annotation.model import SomeUnicodeCodePoint, SomeAddress
from pypy.annotation.model import SomeFloat, unionof, SomeUnicodeString
from pypy.annotation.model import SomePBC, SomeInstance, SomeDict
@@ -249,19 +249,19 @@
getbookkeeper().warning("ignoring apply%r" % (stuff,))
return SomeObject()
-def builtin_slice(*args):
- bk = getbookkeeper()
- if len(args) == 1:
- return SomeSlice(
- bk.immutablevalue(None), args[0], bk.immutablevalue(None))
- elif len(args) == 2:
- return SomeSlice(
- args[0], args[1], bk.immutablevalue(None))
- elif len(args) == 3:
- return SomeSlice(
- args[0], args[1], args[2])
- else:
- raise Exception, "bogus call to slice()"
+##def builtin_slice(*args):
+## bk = getbookkeeper()
+## if len(args) == 1:
+## return SomeSlice(
+## bk.immutablevalue(None), args[0], bk.immutablevalue(None))
+## elif len(args) == 2:
+## return SomeSlice(
+## args[0], args[1], bk.immutablevalue(None))
+## elif len(args) == 3:
+## return SomeSlice(
+## args[0], args[1], args[2])
+## else:
+## raise Exception, "bogus call to slice()"
def OSError_init(s_self, *args):
Modified: pypy/branch/getslice/pypy/annotation/model.py
==============================================================================
--- pypy/branch/getslice/pypy/annotation/model.py (original)
+++ pypy/branch/getslice/pypy/annotation/model.py Fri Oct 10 19:38:43 2008
@@ -253,25 +253,6 @@
def can_be_none(self):
return True
-class SomeSlice(SomeObject):
- knowntype = slice
- immutable = True
- def __init__(self, start, stop, step):
- self.start = start
- self.stop = stop
- self.step = step
-
- def constant_indices(self):
- if (self.start.is_immutable_constant() and
- self.stop .is_immutable_constant() and
- self.step .is_immutable_constant()):
- return self.start.const, self.stop.const, self.step.const
- else:
- raise Exception("need constant indices for this slice")
-
- def can_be_none(self):
- return False
-
class SomeTuple(SomeObject):
"Stands for a tuple of known length."
knowntype = tuple
Modified: pypy/branch/getslice/pypy/annotation/test/test_annrpython.py
==============================================================================
--- pypy/branch/getslice/pypy/annotation/test/test_annrpython.py (original)
+++ pypy/branch/getslice/pypy/annotation/test/test_annrpython.py Fri Oct 10 19:38:43 2008
@@ -425,16 +425,6 @@
s_meth = s_example.getattr(iv(methname))
assert isinstance(s_constmeth, annmodel.SomeBuiltin)
- def test_simple_slicing0(self):
- a = self.RPythonAnnotator()
- a.build_types(snippet.simple_slice, [list])
- g = graphof(a, snippet.simple_slice)
- for block in g.iterblocks():
- for op in block.operations:
- if op.opname == "newslice":
- assert isinstance(a.binding(op.result),
- annmodel.SomeSlice)
-
def test_simple_slicing(self):
a = self.RPythonAnnotator()
s = a.build_types(snippet.simple_slice, [list])
@@ -570,11 +560,6 @@
s = a.build_types(operation_always_raising, [int])
assert s == a.bookkeeper.immutablevalue(24)
- def test_slice_union(self):
- a = self.RPythonAnnotator()
- s = a.build_types(snippet.slice_union, [int])
- assert isinstance(s, annmodel.SomeSlice)
-
def test_bltin_code_frame_confusion(self):
a = self.RPythonAnnotator()
a.build_types(snippet.bltin_code_frame_confusion,[])
@@ -3040,6 +3025,28 @@
a.build_types(f, [str])
+ def test_setslice(self):
+ def f():
+ lst = [2, 5, 7]
+ lst[1:2] = [4]
+ return lst
+
+ a = self.RPythonAnnotator()
+ s = a.build_types(f, [])
+ assert isinstance(s, annmodel.SomeList)
+ assert not s.listdef.listitem.resized
+
+ def test_delslice(self):
+ def f():
+ lst = [2, 5, 7]
+ del lst[1:2]
+ return lst
+
+ a = self.RPythonAnnotator()
+ s = a.build_types(f, [])
+ assert isinstance(s, annmodel.SomeList)
+ assert s.listdef.listitem.resized
+
def test_listitem_no_mutating(self):
from pypy.rlib.debug import check_annotation
called = []
Modified: pypy/branch/getslice/pypy/annotation/unaryop.py
==============================================================================
--- pypy/branch/getslice/pypy/annotation/unaryop.py (original)
+++ pypy/branch/getslice/pypy/annotation/unaryop.py Fri Oct 10 19:38:43 2008
@@ -24,6 +24,7 @@
'iter', 'next', 'invert', 'type', 'issubtype',
'pos', 'neg', 'nonzero', 'abs', 'hex', 'oct',
'ord', 'int', 'float', 'long', 'id',
+ 'getslice', 'setslice', 'delslice',
'neg_ovf', 'abs_ovf', 'hint', 'unicode', 'unichr'])
for opname in UNARY_OPERATIONS:
@@ -274,6 +275,12 @@
s_item.hash() # record that we need the hash of each item
return SomeInteger()
+ def getslice(tup, s_start, s_stop):
+ assert s_start.is_immutable_constant(),"tuple slicing: needs constants"
+ assert s_stop.is_immutable_constant(), "tuple slicing: needs constants"
+ items = tup.items[s_start.const:s_stop.const]
+ return SomeTuple(items)
+
class __extend__(SomeList):
@@ -283,11 +290,9 @@
def method_extend(lst, s_iterable):
lst.listdef.resize()
- if isinstance(s_iterable, SomeList): # unify the two lists
- lst.listdef.agree(s_iterable.listdef)
- else:
- s_iter = s_iterable.iter()
- lst.method_append(s_iter.next())
+ if not isinstance(s_iterable, SomeList):
+ raise Exception("list.extend(x): x must be a list")
+ lst.listdef.agree(s_iterable.listdef)
def method_reverse(lst):
lst.listdef.mutate()
@@ -338,6 +343,28 @@
lst = lst.listdef.offspring()
return lst
+ def getslice(lst, s_start, s_stop):
+ check_negative_slice(s_start, s_stop)
+ return lst.listdef.offspring()
+
+ def setslice(lst, s_start, s_stop, s_iterable):
+ check_negative_slice(s_start, s_stop)
+ if not isinstance(s_iterable, SomeList):
+ raise Exception("list[start:stop] = x: x must be a list")
+ lst.listdef.agree(s_iterable.listdef)
+ # note that setslice is not allowed to resize a list in RPython
+
+ def delslice(lst, s_start, s_stop):
+ check_negative_slice(s_start, s_stop)
+ lst.listdef.resize()
+
+def check_negative_slice(s_start, s_stop):
+ if isinstance(s_start, SomeInteger) and not s_start.nonneg:
+ raise TypeError("slicing: not proven to have non-negative start")
+ if isinstance(s_stop, SomeInteger) and not s_stop.nonneg and \
+ getattr(s_stop, 'const', 0) != -1:
+ raise TypeError("slicing: not proven to have non-negative stop")
+
class __extend__(SomeDict):
@@ -463,6 +490,10 @@
def method_replace(str, s1, s2):
return str.basestringclass()
+ def getslice(str, s_start, s_stop):
+ check_negative_slice(s_start, s_stop)
+ return str.basestringclass()
+
class __extend__(SomeUnicodeString):
def method_encode(uni, s_enc):
if not s_enc.is_constant():
Modified: pypy/branch/getslice/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/branch/getslice/pypy/interpreter/baseobjspace.py (original)
+++ pypy/branch/getslice/pypy/interpreter/baseobjspace.py Fri Oct 10 19:38:43 2008
@@ -588,17 +588,6 @@
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,
@@ -1032,6 +1021,9 @@
('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/getslice/pypy/objspace/descroperation.py
==============================================================================
--- pypy/branch/getslice/pypy/objspace/descroperation.py (original)
+++ pypy/branch/getslice/pypy/objspace/descroperation.py Fri Oct 10 19:38:43 2008
@@ -228,6 +228,30 @@
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)
@@ -453,6 +477,35 @@
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):
@@ -649,5 +702,3 @@
'ord', 'unichr', 'unicode']:
raise Exception, "missing def for operation %s" % _name
-
-
Modified: pypy/branch/getslice/pypy/objspace/flow/objspace.py
==============================================================================
--- pypy/branch/getslice/pypy/objspace/flow/objspace.py (original)
+++ pypy/branch/getslice/pypy/objspace/flow/objspace.py Fri Oct 10 19:38:43 2008
@@ -103,7 +103,7 @@
return Constant(slice(self.unwrap(w_start),
self.unwrap(w_stop),
self.unwrap(w_step)))
- return self.do_operation('newslice', w_start, w_stop, w_step)
+ raise Exception("not supported in RPython: extended slicing")
def wrap(self, obj):
if isinstance(obj, (Variable, Constant)):
Modified: pypy/branch/getslice/pypy/objspace/reflective.py
==============================================================================
--- pypy/branch/getslice/pypy/objspace/reflective.py (original)
+++ pypy/branch/getslice/pypy/objspace/reflective.py Fri Oct 10 19:38:43 2008
@@ -89,6 +89,14 @@
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/getslice/pypy/objspace/std/builtinshortcut.py
==============================================================================
--- pypy/branch/getslice/pypy/objspace/std/builtinshortcut.py (original)
+++ pypy/branch/getslice/pypy/objspace/std/builtinshortcut.py Fri Oct 10 19:38:43 2008
@@ -32,10 +32,16 @@
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)
- 'delitem', 'abs', 'hex', 'oct', # rare stuff?
+ 'getslice', 'setslice', 'delslice', # see below
+ 'delitem', # rare stuff?
+ '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/getslice/pypy/objspace/std/listobject.py
==============================================================================
--- pypy/branch/getslice/pypy/objspace/std/listobject.py (original)
+++ pypy/branch/getslice/pypy/objspace/std/listobject.py Fri Oct 10 19:38:43 2008
@@ -1,7 +1,7 @@
from pypy.objspace.std.objspace import *
from pypy.objspace.std.inttype import wrapint
from pypy.objspace.std.listtype import get_list_index
-from pypy.objspace.std.sliceobject import W_SliceObject
+from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
from pypy.objspace.std import slicetype
from pypy.interpreter import gateway, baseobjspace
@@ -80,6 +80,21 @@
start += step
return w_res
+def getslice__List_ANY_ANY(space, w_list, w_start, w_stop):
+ length = len(w_list.wrappeditems)
+ start, stop = normalize_simple_slice(space, length, 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):
+ length = len(w_list.wrappeditems)
+ start, stop = normalize_simple_slice(space, length, 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):
+ length = len(w_list.wrappeditems)
+ start, stop = normalize_simple_slice(space, length, 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
@@ -190,38 +205,35 @@
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:
- _del_slice(w_list, start, start+slicelength)
+ assert start >= 0
+ assert slicelength >= 0
+ del w_list.wrappeditems[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:
@@ -229,13 +241,7 @@
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)
@@ -246,23 +252,25 @@
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 = len2 - slicelength
- if delta >= 0:
+ delta = slicelength - len2
+ if delta < 0:
+ delta = -delta
newsize = oldsize + delta
# XXX support this in rlist!
items += [None] * delta
@@ -271,9 +279,10 @@
while i >= lim:
items[i] = items[i-delta]
i -= 1
+ elif start >= 0:
+ del items[start:start+delta]
else:
- # shrinking requires the careful memory management of _del_slice()
- _del_slice(w_list, start, start-delta)
+ assert delta==0
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" %
@@ -290,14 +299,13 @@
items[start] = sequence2[i]
start -= step
i -= 1
- return space.w_None
+ return
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):
@@ -350,26 +358,6 @@
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/getslice/pypy/objspace/std/objspace.py
==============================================================================
--- pypy/branch/getslice/pypy/objspace/std/objspace.py (original)
+++ pypy/branch/getslice/pypy/objspace/std/objspace.py Fri Oct 10 19:38:43 2008
@@ -764,33 +764,6 @@
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)
@@ -820,32 +793,3 @@
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/getslice/pypy/objspace/std/rangeobject.py
==============================================================================
--- pypy/branch/getslice/pypy/objspace/std/rangeobject.py (original)
+++ pypy/branch/getslice/pypy/objspace/std/rangeobject.py Fri Oct 10 19:38:43 2008
@@ -1,7 +1,7 @@
from pypy.objspace.std.objspace import *
from pypy.objspace.std.noneobject import W_NoneObject
from pypy.objspace.std.inttype import wrapint
-from pypy.objspace.std.sliceobject import W_SliceObject
+from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
from pypy.objspace.std.listobject import W_ListObject
from pypy.objspace.std import listtype
from pypy.objspace.std import iterobject
@@ -100,6 +100,17 @@
rangestep = w_rangelist.step * step
return W_RangeListObject(rangestart, rangestep, slicelength)
+def getslice__RangeList_ANY_ANY(space, w_rangelist, w_start, w_stop):
+ if w_rangelist.w_list is not None:
+ return space.getslice(w_rangelist.w_list, w_start, w_stop)
+ length = w_rangelist.length
+ start, stop = normalize_simple_slice(space, length, w_start, w_stop)
+ slicelength = stop - start
+ assert slicelength >= 0
+ rangestart = w_rangelist.getitem_unchecked(start)
+ rangestep = w_rangelist.step
+ return W_RangeListObject(rangestart, rangestep, slicelength)
+
def iter__RangeList(space, w_rangelist):
return W_RangeIterObject(w_rangelist)
Modified: pypy/branch/getslice/pypy/objspace/std/ropeobject.py
==============================================================================
--- pypy/branch/getslice/pypy/objspace/std/ropeobject.py (original)
+++ pypy/branch/getslice/pypy/objspace/std/ropeobject.py Fri Oct 10 19:38:43 2008
@@ -2,7 +2,7 @@
from pypy.interpreter import gateway
from pypy.rlib.objectmodel import we_are_translated
from pypy.objspace.std.inttype import wrapint
-from pypy.objspace.std.sliceobject import W_SliceObject
+from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
from pypy.objspace.std import slicetype
from pypy.objspace.std.listobject import W_ListObject
from pypy.objspace.std.noneobject import W_NoneObject
@@ -693,6 +693,15 @@
return W_RopeObject.EMPTY
return W_RopeObject(rope.getslice(node, start, stop, step, sl))
+def getslice__Rope_ANY_ANY(space, w_str, w_start, w_stop):
+ node = w_str._node
+ length = node.length()
+ start, stop = normalize_simple_slice(space, length, w_start, w_stop)
+ sl = stop - start
+ if sl == 0:
+ return W_RopeObject.EMPTY
+ return W_RopeObject(rope.getslice(node, start, stop, 1, sl))
+
def mul_string_times(space, w_str, w_times):
try:
mul = space.getindex_w(w_times, space.w_OverflowError)
Modified: pypy/branch/getslice/pypy/objspace/std/ropeunicodeobject.py
==============================================================================
--- pypy/branch/getslice/pypy/objspace/std/ropeunicodeobject.py (original)
+++ pypy/branch/getslice/pypy/objspace/std/ropeunicodeobject.py Fri Oct 10 19:38:43 2008
@@ -5,7 +5,7 @@
from pypy.objspace.std.ropeobject import W_RopeObject
from pypy.objspace.std.noneobject import W_NoneObject
from pypy.rlib import rope
-from pypy.objspace.std.sliceobject import W_SliceObject
+from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
from pypy.objspace.std import slicetype
from pypy.objspace.std.tupleobject import W_TupleObject
from pypy.rlib.rarithmetic import intmask, ovfcheck
@@ -287,6 +287,15 @@
return W_RopeUnicodeObject.EMPTY
return W_RopeUnicodeObject(rope.getslice(node, start, stop, step, sl))
+def getslice__RopeUnicode_ANY_ANY(space, w_uni, w_start, w_stop):
+ node = w_uni._node
+ length = node.length()
+ start, stop = normalize_simple_slice(space, length, w_start, w_stop)
+ sl = stop - start
+ if sl == 0:
+ return W_RopeUnicodeObject.EMPTY
+ return W_RopeUnicodeObject(rope.getslice(node, start, stop, 1, sl))
+
def mul__RopeUnicode_ANY(space, w_uni, w_times):
try:
times = space.getindex_w(w_times, space.w_OverflowError)
Modified: pypy/branch/getslice/pypy/objspace/std/sliceobject.py
==============================================================================
--- pypy/branch/getslice/pypy/objspace/std/sliceobject.py (original)
+++ pypy/branch/getslice/pypy/objspace/std/sliceobject.py Fri Oct 10 19:38:43 2008
@@ -79,6 +79,19 @@
registerimplementation(W_SliceObject)
+def normalize_simple_slice(space, length, w_start, w_stop):
+ """Helper for the {get,set,del}slice multimethod implementations."""
+ start = space.int_w(w_start)
+ stop = space.int_w(w_stop)
+ if start < 0:
+ start = 0
+ if stop > length:
+ stop = length
+ if stop < start:
+ stop = start
+ return start, stop
+
+
repr__Slice = gateway.applevel("""
def repr__Slice(aslice):
return 'slice(%r, %r, %r)' % (aslice.start, aslice.stop, aslice.step)
Modified: pypy/branch/getslice/pypy/objspace/std/stringobject.py
==============================================================================
--- pypy/branch/getslice/pypy/objspace/std/stringobject.py (original)
+++ pypy/branch/getslice/pypy/objspace/std/stringobject.py Fri Oct 10 19:38:43 2008
@@ -5,7 +5,7 @@
from pypy.rlib.rarithmetic import ovfcheck, _hash_string
from pypy.rlib.objectmodel import we_are_translated
from pypy.objspace.std.inttype import wrapint
-from pypy.objspace.std.sliceobject import W_SliceObject
+from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
from pypy.objspace.std import slicetype
from pypy.objspace.std.listobject import W_ListObject
from pypy.objspace.std.noneobject import W_NoneObject
@@ -803,6 +803,14 @@
str = "".join([s[start + i*step] for i in range(sl)])
return wrapstr(space, str)
+def getslice__String_ANY_ANY(space, w_str, w_start, w_stop):
+ s = w_str._value
+ start, stop = normalize_simple_slice(space, len(s), w_start, w_stop)
+ if start == stop:
+ return W_StringObject.EMPTY
+ else:
+ return sliced(space, s, start, stop)
+
def mul_string_times(space, w_str, w_times):
try:
mul = space.getindex_w(w_times, space.w_OverflowError)
Modified: pypy/branch/getslice/pypy/objspace/std/strsliceobject.py
==============================================================================
--- pypy/branch/getslice/pypy/objspace/std/strsliceobject.py (original)
+++ pypy/branch/getslice/pypy/objspace/std/strsliceobject.py Fri Oct 10 19:38:43 2008
@@ -1,7 +1,7 @@
from pypy.objspace.std.objspace import *
from pypy.objspace.std.stringobject import W_StringObject
from pypy.objspace.std.unicodeobject import delegate_String2Unicode
-from pypy.objspace.std.sliceobject import W_SliceObject
+from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
from pypy.objspace.std.tupleobject import W_TupleObject
from pypy.objspace.std import slicetype
from pypy.objspace.std.inttype import wrapint
@@ -194,6 +194,18 @@
str = "".join([s[start + i*step] for i in range(sl)])
return wrapstr(space, str)
+def getslice__StringSlice_ANY_ANY(space, w_str, w_start, w_stop):
+ length = w_str.stop - w_str.start
+ start, stop = normalize_simple_slice(space, length, w_start, w_stop)
+ sl = stop - start
+ if sl == 0:
+ return W_StringObject.EMPTY
+ else:
+ s = w_str.str
+ start = w_str.start + start
+ stop = w_str.start + stop
+ return W_StringSliceObject(s, start, stop)
+
def len__StringSlice(space, w_str):
return space.wrap(w_str.stop - w_str.start)
Modified: pypy/branch/getslice/pypy/objspace/std/test/test_builtinshortcut.py
==============================================================================
--- pypy/branch/getslice/pypy/objspace/std/test/test_builtinshortcut.py (original)
+++ pypy/branch/getslice/pypy/objspace/std/test/test_builtinshortcut.py Fri Oct 10 19:38:43 2008
@@ -1,5 +1,6 @@
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}
@@ -38,3 +39,8 @@
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/getslice/pypy/objspace/std/test/test_listmultiobject.py
==============================================================================
--- pypy/branch/getslice/pypy/objspace/std/test/test_listmultiobject.py (original)
+++ pypy/branch/getslice/pypy/objspace/std/test/test_listmultiobject.py Fri Oct 10 19:38:43 2008
@@ -39,6 +39,15 @@
# 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/getslice/pypy/objspace/std/test/test_listobject.py
==============================================================================
--- pypy/branch/getslice/pypy/objspace/std/test/test_listobject.py (original)
+++ pypy/branch/getslice/pypy/objspace/std/test/test_listobject.py Fri Oct 10 19:38:43 2008
@@ -754,3 +754,18 @@
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/getslice/pypy/objspace/std/test/test_rangeobject.py
==============================================================================
--- pypy/branch/getslice/pypy/objspace/std/test/test_rangeobject.py (original)
+++ pypy/branch/getslice/pypy/objspace/std/test/test_rangeobject.py Fri Oct 10 19:38:43 2008
@@ -29,6 +29,14 @@
def test_getitem_slice(self):
result = []
r = range(1, 100, 2)
+ for i in r[10:15]:
+ result.append(i)
+ assert result == [21, 23, 25, 27, 29]
+ assert self.not_forced(r)
+
+ def test_getitem_extended_slice(self):
+ result = []
+ r = range(1, 100, 2)
for i in r[40:30:-2]:
result.append(i)
assert result == [81, 77, 73, 69, 65]
Modified: pypy/branch/getslice/pypy/objspace/std/test/test_stringobject.py
==============================================================================
--- pypy/branch/getslice/pypy/objspace/std/test/test_stringobject.py (original)
+++ pypy/branch/getslice/pypy/objspace/std/test/test_stringobject.py Fri Oct 10 19:38:43 2008
@@ -714,6 +714,20 @@
assert x.rstrip(y) == ''
assert x.lstrip(y) == ''
+ def test_getslice(self):
+ assert "foobar".__getslice__(4, 4321) == "ar"
+ s = "abc"
+ assert s[:] == "abc"
+ assert s[1:] == "bc"
+ assert s[:2] == "ab"
+ assert s[1:2] == "b"
+ assert s[-2:] == "bc"
+ assert s[:-1] == "ab"
+ assert s[-2:2] == "b"
+ assert s[1:-1] == "b"
+ assert s[-2:-1] == "b"
+
+
class AppTestPrebuilt(AppTestStringObject):
def setup_class(cls):
cls.space = gettestobjspace(**{"objspace.std.withprebuiltchar": True})
Modified: pypy/branch/getslice/pypy/objspace/std/test/test_strsliceobject.py
==============================================================================
--- pypy/branch/getslice/pypy/objspace/std/test/test_strsliceobject.py (original)
+++ pypy/branch/getslice/pypy/objspace/std/test/test_strsliceobject.py Fri Oct 10 19:38:43 2008
@@ -133,3 +133,16 @@
assert s.count("X") == 100
assert s.count("Y") == 100
assert self.not_forced(s)
+
+ def test_extended_slice(self):
+ import __pypy__
+ def slice1(s): return (s*3)[len(s):-len(s)]
+ s = slice1('0123456789' * 20)
+ assert len(s) == 200
+ assert self.not_forced(s)
+ t = s[::-1]
+ assert t == '9876543210' * 20
+ assert not self.not_forced(t)
+ u = s[slice(10, 20)]
+ assert self.not_forced(u)
+ assert u == '0123456789'
Modified: pypy/branch/getslice/pypy/objspace/std/test/test_tupleobject.py
==============================================================================
--- pypy/branch/getslice/pypy/objspace/std/test/test_tupleobject.py (original)
+++ pypy/branch/getslice/pypy/objspace/std/test/test_tupleobject.py Fri Oct 10 19:38:43 2008
@@ -318,3 +318,5 @@
assert repr(()) == '()'
assert repr((1,2,3)) == '(1, 2, 3)'
+ def test_getslice(self):
+ assert ('a', 'b', 'c').__getslice__(-17, 2) == ('a', 'b')
Modified: pypy/branch/getslice/pypy/objspace/std/test/test_unicodeobject.py
==============================================================================
--- pypy/branch/getslice/pypy/objspace/std/test/test_unicodeobject.py (original)
+++ pypy/branch/getslice/pypy/objspace/std/test/test_unicodeobject.py Fri Oct 10 19:38:43 2008
@@ -641,3 +641,15 @@
assert unicode(Y()).__class__ is X
+ def test_getslice(self):
+ assert u'123456'.__getslice__(1, 5) == u'2345'
+ s = u"abc"
+ assert s[:] == "abc"
+ assert s[1:] == "bc"
+ assert s[:2] == "ab"
+ assert s[1:2] == "b"
+ assert s[-2:] == "bc"
+ assert s[:-1] == "ab"
+ assert s[-2:2] == "b"
+ assert s[1:-1] == "b"
+ assert s[-2:-1] == "b"
Modified: pypy/branch/getslice/pypy/objspace/std/tupleobject.py
==============================================================================
--- pypy/branch/getslice/pypy/objspace/std/tupleobject.py (original)
+++ pypy/branch/getslice/pypy/objspace/std/tupleobject.py Fri Oct 10 19:38:43 2008
@@ -1,7 +1,7 @@
from pypy.objspace.std.objspace import *
from pypy.objspace.std.inttype import wrapint
from pypy.rlib.rarithmetic import intmask
-from pypy.objspace.std.sliceobject import W_SliceObject
+from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
from pypy.interpreter import gateway
from pypy.rlib.debug import make_sure_not_resized
@@ -53,6 +53,11 @@
start += step
return W_TupleObject(subitems)
+def getslice__Tuple_ANY_ANY(space, w_tuple, w_start, w_stop):
+ length = len(w_tuple.wrappeditems)
+ start, stop = normalize_simple_slice(space, length, w_start, w_stop)
+ return W_TupleObject(w_tuple.wrappeditems[start:stop])
+
def contains__Tuple_ANY(space, w_tuple, w_obj):
for w_item in w_tuple.wrappeditems:
if space.eq_w(w_item, w_obj):
Modified: pypy/branch/getslice/pypy/objspace/std/unicodeobject.py
==============================================================================
--- pypy/branch/getslice/pypy/objspace/std/unicodeobject.py (original)
+++ pypy/branch/getslice/pypy/objspace/std/unicodeobject.py Fri Oct 10 19:38:43 2008
@@ -3,7 +3,7 @@
from pypy.objspace.std.stringobject import W_StringObject
from pypy.objspace.std.ropeobject import W_RopeObject
from pypy.objspace.std.noneobject import W_NoneObject
-from pypy.objspace.std.sliceobject import W_SliceObject
+from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
from pypy.objspace.std import slicetype
from pypy.objspace.std.tupleobject import W_TupleObject
from pypy.rlib.rarithmetic import intmask, ovfcheck
@@ -247,6 +247,11 @@
r = u"".join([uni[start + i*step] for i in range(sl)])
return W_UnicodeObject(r)
+def getslice__Unicode_ANY_ANY(space, w_uni, w_start, w_stop):
+ uni = w_uni._value
+ start, stop = normalize_simple_slice(space, len(uni), w_start, w_stop)
+ return W_UnicodeObject(uni[start:stop])
+
def mul__Unicode_ANY(space, w_uni, w_times):
try:
times = space.getindex_w(w_times, space.w_OverflowError)
Modified: pypy/branch/getslice/pypy/objspace/thunk.py
==============================================================================
--- pypy/branch/getslice/pypy/objspace/thunk.py (original)
+++ pypy/branch/getslice/pypy/objspace/thunk.py Fri Oct 10 19:38:43 2008
@@ -193,6 +193,13 @@
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))
Modified: pypy/branch/getslice/pypy/rpython/lltypesystem/rlist.py
==============================================================================
--- pypy/branch/getslice/pypy/rpython/lltypesystem/rlist.py (original)
+++ pypy/branch/getslice/pypy/rpython/lltypesystem/rlist.py Fri Oct 10 19:38:43 2008
@@ -7,9 +7,6 @@
AbstractFixedSizeListRepr, AbstractListIteratorRepr, rtype_newlist, \
rtype_alloc_and_set, ll_setitem_nonneg, ADTIList, ADTIFixedList
from pypy.rpython.rlist import dum_nocheck, dum_checkidx
-from pypy.rpython.lltypesystem.rslice import SliceRepr
-from pypy.rpython.lltypesystem.rslice import startstop_slice_repr, startonly_slice_repr
-from pypy.rpython.lltypesystem.rslice import minusone_slice_repr
from pypy.rpython.lltypesystem.lltype import \
GcForwardReference, Ptr, GcArray, GcStruct, \
Void, Signed, malloc, typeOf, Primitive, \
Modified: pypy/branch/getslice/pypy/rpython/ootypesystem/rlist.py
==============================================================================
--- pypy/branch/getslice/pypy/rpython/ootypesystem/rlist.py (original)
+++ pypy/branch/getslice/pypy/rpython/ootypesystem/rlist.py Fri Oct 10 19:38:43 2008
@@ -5,8 +5,6 @@
from pypy.rpython.rmodel import inputconst, externalvsinternal
from pypy.rpython.lltypesystem.lltype import Signed, Void
from pypy.rpython.ootypesystem import ootype
-from pypy.rpython.ootypesystem.rslice import SliceRepr, \
- startstop_slice_repr, startonly_slice_repr, minusone_slice_repr
from pypy.rpython.ootypesystem import rstr
Modified: pypy/branch/getslice/pypy/rpython/rlist.py
==============================================================================
--- pypy/branch/getslice/pypy/rpython/rlist.py (original)
+++ pypy/branch/getslice/pypy/rpython/rlist.py Fri Oct 10 19:38:43 2008
@@ -3,7 +3,6 @@
from pypy.annotation import model as annmodel
from pypy.rpython.error import TyperError
from pypy.rpython.rmodel import Repr, IteratorRepr, IntegerRepr, inputconst
-from pypy.rpython.rslice import AbstractSliceRepr
from pypy.rpython.rstr import AbstractStringRepr, AbstractCharRepr
from pypy.rpython.lltypesystem.lltype import typeOf, Ptr, Void, Signed, Bool
from pypy.rpython.lltypesystem.lltype import nullptr, Char, UniChar
@@ -403,47 +402,30 @@
return v_lst1
-class __extend__(pairtype(AbstractBaseListRepr, AbstractSliceRepr)):
+class __extend__(AbstractBaseListRepr):
- def rtype_getitem((r_lst, r_slic), hop):
- rs = r_lst.rtyper.type_system.rslice
+ def rtype_getslice(r_lst, hop):
cRESLIST = hop.inputconst(Void, hop.r_result.LIST)
- if r_slic == rs.startonly_slice_repr:
- v_lst, v_start = hop.inputargs(r_lst, rs.startonly_slice_repr)
- return hop.gendirectcall(ll_listslice_startonly, cRESLIST, v_lst, v_start)
- if r_slic == rs.startstop_slice_repr:
- v_lst, v_slice = hop.inputargs(r_lst, rs.startstop_slice_repr)
- return hop.gendirectcall(ll_listslice, cRESLIST, v_lst, v_slice)
- if r_slic == rs.minusone_slice_repr:
- v_lst, v_ignored = hop.inputargs(r_lst, rs.minusone_slice_repr)
- return hop.gendirectcall(ll_listslice_minusone, cRESLIST, v_lst)
- raise TyperError('getitem does not support slices with %r' % (r_slic,))
-
- def rtype_setitem((r_lst, r_slic), hop):
- #if r_slic == startonly_slice_repr:
- # not implemented
- rs = r_lst.rtyper.type_system.rslice
- if r_slic == rs.startstop_slice_repr:
- v_lst, v_slice, v_lst2 = hop.inputargs(r_lst, rs.startstop_slice_repr,
- hop.args_r[2])
- hop.gendirectcall(ll_listsetslice, v_lst, v_slice, v_lst2)
- return
- raise TyperError('setitem does not support slices with %r' % (r_slic,))
-
-
-class __extend__(pairtype(AbstractListRepr, AbstractSliceRepr)):
-
- def rtype_delitem((r_lst, r_slic), hop):
- rs = r_lst.rtyper.type_system.rslice
- if r_slic == rs.startonly_slice_repr:
- v_lst, v_start = hop.inputargs(r_lst, rs.startonly_slice_repr)
- hop.gendirectcall(ll_listdelslice_startonly, v_lst, v_start)
- return
- if r_slic == rs.startstop_slice_repr:
- v_lst, v_slice = hop.inputargs(r_lst, rs.startstop_slice_repr)
- hop.gendirectcall(ll_listdelslice, v_lst, v_slice)
- return
- raise TyperError('delitem does not support slices with %r' % (r_slic,))
+ v_lst = hop.inputarg(r_lst, arg=0)
+ kind, vlist = hop.decompose_slice_args()
+ ll_listslice = globals()['ll_listslice_%s' % kind]
+ return hop.gendirectcall(ll_listslice, cRESLIST, v_lst, *vlist)
+
+ def rtype_setslice(r_lst, hop):
+ v_lst = hop.inputarg(r_lst, arg=0)
+ kind, vlist = hop.decompose_slice_args()
+ if kind != 'startstop':
+ raise TyperError('list.setitem does not support %r slices' % (
+ kind,))
+ v_start, v_stop = vlist
+ v_lst2 = hop.inputarg(hop.args_r[3], arg=3)
+ hop.gendirectcall(ll_listsetslice, v_lst, v_start, v_stop, v_lst2)
+
+ def rtype_delslice(r_lst, hop):
+ v_lst = hop.inputarg(r_lst, arg=0)
+ kind, vlist = hop.decompose_slice_args()
+ ll_listdelslice = globals()['ll_listdelslice_%s' % kind]
+ return hop.gendirectcall(ll_listdelslice, v_lst, *vlist)
# ____________________________________________________________
@@ -868,9 +850,7 @@
j += 1
return l
-def ll_listslice(RESLIST, l1, slice):
- start = slice.start
- stop = slice.stop
+def ll_listslice_startstop(RESLIST, l1, start, stop):
length = l1.ll_length()
ll_assert(start >= 0, "unexpectedly negative list slice start")
ll_assert(start <= length, "list slice start larger than list length")
@@ -909,9 +889,7 @@
j -= 1
l._ll_resize_le(newlength)
-def ll_listdelslice(l, slice):
- start = slice.start
- stop = slice.stop
+def ll_listdelslice_startstop(l, start, stop):
length = l.ll_length()
ll_assert(start >= 0, "del l[start:x] with unexpectedly negative start")
ll_assert(start <= length, "del l[start:x] with start > len(l)")
@@ -933,12 +911,11 @@
j -= 1
l._ll_resize_le(newlength)
-def ll_listsetslice(l1, slice, l2):
+def ll_listsetslice(l1, start, stop, l2):
count = l2.ll_length()
- start = slice.start
ll_assert(start >= 0, "l[start:x] = l with unexpectedly negative start")
ll_assert(start <= l1.ll_length(), "l[start:x] = l with start > len(l)")
- ll_assert(count == slice.stop - start,
+ ll_assert(count == stop - start,
"setslice cannot resize lists in RPython")
# XXX but it should be easy enough to support, soon
j = start
Modified: pypy/branch/getslice/pypy/rpython/rstr.py
==============================================================================
--- pypy/branch/getslice/pypy/rpython/rstr.py (original)
+++ pypy/branch/getslice/pypy/rpython/rstr.py Fri Oct 10 19:38:43 2008
@@ -5,7 +5,6 @@
from pypy.rpython.rmodel import IntegerRepr, IteratorRepr
from pypy.rpython.rmodel import inputconst, Repr
from pypy.rpython.rtuple import AbstractTupleRepr
-from pypy.rpython.rslice import AbstractSliceRepr
from pypy.rpython import rint
from pypy.rpython.lltypesystem.lltype import Signed, Bool, Void, UniChar,\
cast_primitive
@@ -331,22 +330,22 @@
rtype_getitem_idx_key = rtype_getitem_idx
-class __extend__(pairtype(AbstractStringRepr, AbstractSliceRepr)):
+##class __extend__(pairtype(AbstractStringRepr, AbstractSliceRepr)):
- def rtype_getitem((r_str, r_slic), hop):
- string_repr = r_str.repr
- rslice = hop.rtyper.type_system.rslice
-
- if r_slic == rslice.startonly_slice_repr:
- v_str, v_start = hop.inputargs(string_repr, rslice.startonly_slice_repr)
- return hop.gendirectcall(r_str.ll.ll_stringslice_startonly, v_str, v_start)
- if r_slic == rslice.startstop_slice_repr:
- v_str, v_slice = hop.inputargs(string_repr, rslice.startstop_slice_repr)
- return hop.gendirectcall(r_str.ll.ll_stringslice, v_str, v_slice)
- if r_slic == rslice.minusone_slice_repr:
- v_str, v_ignored = hop.inputargs(string_repr, rslice.minusone_slice_repr)
- return hop.gendirectcall(r_str.ll.ll_stringslice_minusone, v_str)
- raise TyperError(r_slic)
+## def rtype_getitem((r_str, r_slic), hop):
+## string_repr = r_str.repr
+## rslice = hop.rtyper.type_system.rslice
+
+## if r_slic == rslice.startonly_slice_repr:
+## v_str, v_start = hop.inputargs(string_repr, rslice.startonly_slice_repr)
+## return hop.gendirectcall(r_str.ll.ll_stringslice_startonly, v_str, v_start)
+## if r_slic == rslice.startstop_slice_repr:
+## v_str, v_slice = hop.inputargs(string_repr, rslice.startstop_slice_repr)
+## return hop.gendirectcall(r_str.ll.ll_stringslice, v_str, v_slice)
+## if r_slic == rslice.minusone_slice_repr:
+## v_str, v_ignored = hop.inputargs(string_repr, rslice.minusone_slice_repr)
+## return hop.gendirectcall(r_str.ll.ll_stringslice_minusone, v_str)
+## raise TyperError(r_slic)
class __extend__(pairtype(AbstractStringRepr, AbstractStringRepr)):
def rtype_add((r_str1, r_str2), hop):
Modified: pypy/branch/getslice/pypy/rpython/rtuple.py
==============================================================================
--- pypy/branch/getslice/pypy/rpython/rtuple.py (original)
+++ pypy/branch/getslice/pypy/rpython/rtuple.py Fri Oct 10 19:38:43 2008
@@ -6,7 +6,6 @@
from pypy.rpython.rmodel import Repr, IntegerRepr, inputconst
from pypy.rpython.rmodel import IteratorRepr
from pypy.rpython.rmodel import externalvsinternal
-from pypy.rpython.rslice import AbstractSliceRepr
from pypy.rpython.lltypesystem.lltype import Void, Signed, Bool
from pypy.rlib.rarithmetic import intmask
from pypy.rlib.unroll import unrolling_iterable
@@ -242,18 +241,18 @@
index = v_index.value
return r_tup.getitem(hop.llops, v_tuple, index)
-class __extend__(pairtype(AbstractTupleRepr, AbstractSliceRepr)):
+##class __extend__(pairtype(AbstractTupleRepr, AbstractSliceRepr)):
- def rtype_getitem((r_tup, r_slice), hop):
- v_tup = hop.inputarg(r_tup, arg=0)
- s_slice = hop.args_s[1]
- start, stop, step = s_slice.constant_indices()
- indices = range(len(r_tup.items_r))[start:stop:step]
- assert len(indices) == len(hop.r_result.items_r)
-
- items_v = [r_tup.getitem_internal(hop.llops, v_tup, i)
- for i in indices]
- return hop.r_result.newtuple(hop.llops, hop.r_result, items_v)
+## def rtype_getitem((r_tup, r_slice), hop):
+## v_tup = hop.inputarg(r_tup, arg=0)
+## s_slice = hop.args_s[1]
+## start, stop, step = s_slice.constant_indices()
+## indices = range(len(r_tup.items_r))[start:stop:step]
+## assert len(indices) == len(hop.r_result.items_r)
+
+## items_v = [r_tup.getitem_internal(hop.llops, v_tup, i)
+## for i in indices]
+## return hop.r_result.newtuple(hop.llops, hop.r_result, items_v)
class __extend__(pairtype(AbstractTupleRepr, Repr)):
def rtype_contains((r_tup, r_item), hop):
Modified: pypy/branch/getslice/pypy/rpython/rtyper.py
==============================================================================
--- pypy/branch/getslice/pypy/rpython/rtyper.py (original)
+++ pypy/branch/getslice/pypy/rpython/rtyper.py Fri Oct 10 19:38:43 2008
@@ -811,6 +811,32 @@
return # ignored for high-level ops before the last one in the block
self.llops.llop_raising_exceptions = "removed"
+ def decompose_slice_args(self):
+ # Select which kind of slicing is needed. We support:
+ # * [start:]
+ # * [start:stop]
+ # * [:-1]
+ s_start = self.args_s[1]
+ s_stop = self.args_s[2]
+ if (s_start.is_constant() and s_start.const in (None, 0) and
+ s_stop.is_constant() and s_stop.const == -1):
+ return "minusone", []
+ if isinstance(s_start, annmodel.SomeInteger):
+ if not s_start.nonneg:
+ raise TyperError("slice start must be proved non-negative")
+ if isinstance(s_stop, annmodel.SomeInteger):
+ if not s_stop.nonneg:
+ raise TyperError("slice stop must be proved non-negative")
+ if s_start.is_constant() and s_start.const is None:
+ v_start = inputconst(Signed, 0)
+ else:
+ v_start = self.inputarg(Signed, arg=1)
+ if s_stop.is_constant() and s_stop.const is None:
+ return "startonly", [v_start]
+ else:
+ v_stop = self.inputarg(Signed, arg=2)
+ return "startstop", [v_start, v_stop]
+
# ____________________________________________________________
class LowLevelOpList(list):
@@ -935,7 +961,7 @@
# and the rtyper_chooserepr() methods
from pypy.rpython import robject
from pypy.rpython import rint, rbool, rfloat
-from pypy.rpython import rslice, rrange
+from pypy.rpython import rrange
from pypy.rpython import rstr, rdict, rlist
from pypy.rpython import rclass, rbuiltin, rpbc, rspecialcase
from pypy.rpython import rexternalobj
Modified: pypy/branch/getslice/pypy/rpython/test/test_rlist.py
==============================================================================
--- pypy/branch/getslice/pypy/rpython/test/test_rlist.py (original)
+++ pypy/branch/getslice/pypy/rpython/test/test_rlist.py Fri Oct 10 19:38:43 2008
@@ -7,7 +7,6 @@
from pypy.rpython.lltypesystem.rlist import ListRepr, FixedSizeListRepr, ll_newlist, ll_fixed_newlist
from pypy.rpython.lltypesystem import rlist as ll_rlist
from pypy.rpython.ootypesystem import rlist as oo_rlist
-from pypy.rpython.lltypesystem.rslice import ll_newslice
from pypy.rpython.rint import signed_repr
from pypy.translator.translator import TranslationContext
from pypy.objspace.flow.model import Constant, Variable
@@ -58,8 +57,8 @@
self.check_list(ll_listslice_startonly(LIST, l, 4), [])
for start in range(5):
for stop in range(start, 8):
- s = ll_newslice(start, stop)
- self.check_list(ll_listslice(LIST, l, s), [42, 43, 44, 45][start:stop])
+ self.check_list(ll_listslice_startstop(LIST, l, start, stop),
+ [42, 43, 44, 45][start:stop])
def test_rlist_setslice(self):
n = 100
@@ -72,9 +71,8 @@
expected[i] = n
ll_setitem(l2, i, n)
n += 1
- s = ll_newslice(start, stop)
- l2 = ll_listslice(typeOf(l2).TO, l2, s)
- ll_listsetslice(l1, s, l2)
+ l2 = ll_listslice_startstop(typeOf(l2).TO, l2, start, stop)
+ ll_listsetslice(l1, start, stop, l2)
self.check_list(l1, expected)
@@ -129,8 +127,7 @@
for start in range(5):
for stop in range(start, 8):
l = self.sample_list()
- s = ll_newslice(start, stop)
- ll_listdelslice(l, s)
+ ll_listdelslice_startstop(l, start, stop)
expected = [42, 43, 44, 45]
del expected[start:stop]
self.check_list(l, expected)
@@ -380,6 +377,25 @@
assert res.item2 == 8
assert res.item3 == 7
+ def test_delslice(self):
+ def dummyfn():
+ l = [10, 9, 8, 7]
+ del l[:2]
+ return len(l), l[0], l[1]
+ res = self.interpret(dummyfn, ())
+ assert res.item0 == 2
+ assert res.item1 == 8
+ assert res.item2 == 7
+
+ def dummyfn():
+ l = [10, 9, 8, 7]
+ del l[2:]
+ return len(l), l[0], l[1]
+ res = self.interpret(dummyfn, ())
+ assert res.item0 == 2
+ assert res.item1 == 10
+ assert res.item2 == 9
+
def test_bltn_list(self):
def dummyfn():
l1 = [42]
Modified: pypy/branch/getslice/pypy/translator/simplify.py
==============================================================================
--- pypy/branch/getslice/pypy/translator/simplify.py (original)
+++ pypy/branch/getslice/pypy/translator/simplify.py Fri Oct 10 19:38:43 2008
@@ -483,7 +483,7 @@
# (they have no side effects, at least in R-Python)
CanRemove = {}
for _op in '''
- newtuple newlist newdict newslice is_true
+ newtuple newlist newdict is_true
is_ id type issubtype repr str len hash getattr getitem
pos neg nonzero abs hex oct ord invert add sub mul
truediv floordiv div mod divmod pow lshift rshift and_ or_
Modified: pypy/branch/getslice/pypy/translator/transform.py
==============================================================================
--- pypy/branch/getslice/pypy/translator/transform.py (original)
+++ pypy/branch/getslice/pypy/translator/transform.py Fri Oct 10 19:38:43 2008
@@ -112,30 +112,6 @@
op.result)
block.operations[i] = new_op
-# a[b:c]
-# -->
-# d = newslice(b, c, None)
-# e = getitem(a, d)
-# -->
-# e = getslice(a, b, c)
-
-##def transform_slice(self, block_subset): -- not used any more --
-## """Transforms a[b:c] to getslice(a, b, c)."""
-## for block in block_subset:
-## operations = block.operations[:]
-## n_op = len(operations)
-## for i in range(0, n_op-1):
-## op1 = operations[i]
-## op2 = operations[i+1]
-## if (op1.opname == 'newslice' and
-## self.gettype(op1.args[2]) is types.NoneType and
-## op2.opname == 'getitem' and
-## op1.result is op2.args[1]):
-## new_op = SpaceOperation('getslice',
-## (op2.args[0], op1.args[0], op1.args[1]),
-## op2.result)
-## block.operations[i+1:i+2] = [new_op]
-
def transform_dead_op_vars(self, block_subset):
# we redo the same simplification from simplify.py,
More information about the Pypy-commit
mailing list