[pypy-svn] r29323 - in pypy/dist/pypy/objspace/std: . test
arigo at codespeak.net
arigo at codespeak.net
Sun Jun 25 17:51:29 CEST 2006
Author: arigo
Date: Sun Jun 25 17:51:26 2006
New Revision: 29323
Added:
pypy/dist/pypy/objspace/std/strsliceobject.py (contents, props changed)
pypy/dist/pypy/objspace/std/test/test_strsliceobject.py (contents, props changed)
Modified:
pypy/dist/pypy/objspace/std/model.py
pypy/dist/pypy/objspace/std/stringobject.py
pypy/dist/pypy/objspace/std/stringtype.py
Log:
Experimental (and turned off by default): W_StringSliceObject,
representing a slice of an RPython string. Only a few operations are
implemented on it, but by automatic delegation to W_StringObject it
still works transparently.
I guess this should at least check how large the slice will be, and only
use W_StringSliceObject for "large enough" slices.
Modified: pypy/dist/pypy/objspace/std/model.py
==============================================================================
--- pypy/dist/pypy/objspace/std/model.py (original)
+++ pypy/dist/pypy/objspace/std/model.py Sun Jun 25 17:51:26 2006
@@ -9,6 +9,7 @@
import pypy.interpreter.special
WITHSMALLINT = False
+WITHSTRSLICE = False
class StdTypeModel:
@@ -53,6 +54,8 @@
from pypy.objspace.std import listobject
from pypy.objspace.std import dictobject
from pypy.objspace.std import stringobject
+ if WITHSTRSLICE:
+ from pypy.objspace.std import strsliceobject
from pypy.objspace.std import typeobject
from pypy.objspace.std import sliceobject
from pypy.objspace.std import longobject
@@ -93,6 +96,8 @@
self.typeorder[setobject.W_SetIterObject] = []
if WITHSMALLINT:
self.typeorder[smallintobject.W_SmallIntObject] = []
+ if WITHSTRSLICE:
+ self.typeorder[strsliceobject.W_StringSliceObject] = []
for type in self.typeorder:
self.typeorder[type].append((type, None))
@@ -140,6 +145,14 @@
(unicodeobject.W_UnicodeObject, unicodeobject.delegate_String2Unicode),
]
+ if WITHSTRSLICE:
+ self.typeorder[strsliceobject.W_StringSliceObject] += [
+ (stringobject.W_StringObject,
+ strsliceobject.delegate_slice2str),
+ (unicodeobject.W_UnicodeObject,
+ strsliceobject.delegate_slice2unicode),
+ ]
+
# put W_Root everywhere
self.typeorder[W_Root] = []
for type in self.typeorder:
Modified: pypy/dist/pypy/objspace/std/stringobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/stringobject.py (original)
+++ pypy/dist/pypy/objspace/std/stringobject.py Sun Jun 25 17:51:26 2006
@@ -11,8 +11,7 @@
from pypy.objspace.std.noneobject import W_NoneObject
from pypy.objspace.std.tupleobject import W_TupleObject
-# XXX consider reimplementing _value to be a list of characters
-# instead of a plain string
+from pypy.objspace.std.stringtype import sliced
class W_StringObject(W_Object):
@@ -846,7 +845,7 @@
str = ""
elif step == 1:
assert start >= 0 and stop >= 0
- str = s[start:stop]
+ return sliced(s, start, stop)
else:
str = "".join([s[start + i*step] for i in range(sl)])
return W_StringObject(str)
Modified: pypy/dist/pypy/objspace/std/stringtype.py
==============================================================================
--- pypy/dist/pypy/objspace/std/stringtype.py (original)
+++ pypy/dist/pypy/objspace/std/stringtype.py Sun Jun 25 17:51:26 2006
@@ -3,6 +3,17 @@
from sys import maxint
+from pypy.objspace.std.model import WITHSTRSLICE
+if WITHSTRSLICE:
+ def sliced(s, start, stop):
+ from pypy.objspace.std.strsliceobject import W_StringSliceObject
+ return W_StringSliceObject(s, start, stop)
+else:
+ def sliced(s, start, stop):
+ from pypy.objspace.std.stringobject import W_StringObject
+ return W_StringObject(s[start:stop])
+
+
str_join = SMM('join', 2,
doc='S.join(sequence) -> string\n\nReturn a string which is'
' the concatenation of the strings in the\nsequence. '
Added: pypy/dist/pypy/objspace/std/strsliceobject.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/objspace/std/strsliceobject.py Sun Jun 25 17:51:26 2006
@@ -0,0 +1,131 @@
+from pypy.objspace.std.objspace import *
+from pypy.objspace.std.stringobject import W_StringObject
+from pypy.objspace.std.unicodeobject import delegate_String2Unicode
+
+
+class W_StringSliceObject(W_Object):
+ from pypy.objspace.std.stringtype import str_typedef as typedef
+
+ def __init__(w_self, str, start, stop):
+ w_self.str = str
+ w_self.start = start
+ w_self.stop = stop
+
+ def force(w_self):
+ str = w_self.str[w_self.start:w_self.stop]
+ w_self.str = str
+ w_self.start = 0
+ w_self.stop = len(str)
+ return str
+
+ def __repr__(w_self):
+ """ representation for debugging purposes """
+ return "%s(%r[%d:%d])" % (w_self.__class__.__name__,
+ w_self.str, w_self.start, w_self.stop)
+
+
+registerimplementation(W_StringSliceObject)
+
+
+def delegate_slice2str(space, w_strslice):
+ return W_StringObject(w_strslice.force())
+
+def delegate_slice2unicode(space, w_strslice):
+ w_str = W_StringObject(w_strslice.force())
+ return delegate_String2Unicode(space, w_str)
+
+# ____________________________________________________________
+
+def contains__StringSlice_String(space, w_self, w_sub):
+ sub = w_sub._value
+ return space.newbool(w_self.str.find(sub, w_self.start, w_self.stop) >= 0)
+
+
+def _convert_idx_params(space, w_self, w_sub, w_start, w_end):
+ length = w_self.stop - w_self.start
+ sub = w_sub._value
+ w_start = slicetype.adapt_bound(space, w_start, space.wrap(length))
+ w_end = slicetype.adapt_bound(space, w_end, space.wrap(length))
+
+ start = space.int_w(w_start)
+ end = space.int_w(w_end)
+ assert start >= 0
+ assert end >= 0
+
+ return (w_self.str, sub, w_self.start + start, end)
+
+
+def str_find__StringSlice_String_ANY_ANY(space, w_self, w_sub, w_start, w_end):
+
+ (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end)
+ res = self.find(sub, start, end)
+ return space.wrap(res)
+
+def str_rfind__StringSlice_String_ANY_ANY(space, w_self, w_sub, w_start, w_end):
+
+ (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end)
+ res = self.rfind(sub, start, end)
+ return space.wrap(res)
+
+def str_index__StringSlice_String_ANY_ANY(space, w_self, w_sub, w_start, w_end):
+
+ (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end)
+ res = self.find(sub, start, end)
+ if res < 0:
+ raise OperationError(space.w_ValueError,
+ space.wrap("substring not found in string.index"))
+
+ return space.wrap(res)
+
+
+def str_rindex__StringSlice_String_ANY_ANY(space, w_self, w_sub, w_start, w_end):
+
+ (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end)
+ res = self.rfind(sub, start, end)
+ if res < 0:
+ raise OperationError(space.w_ValueError,
+ space.wrap("substring not found in string.rindex"))
+
+ return space.wrap(res)
+
+
+def str_w__StringSlice(space, w_str):
+ return w_str.force()
+
+
+def getitem__StringSlice_ANY(space, w_str, w_index):
+ ival = space.int_w(w_index)
+ slen = w_str.stop - w_str.start
+ if ival < 0:
+ ival += slen
+ if ival < 0 or ival >= slen:
+ exc = space.call_function(space.w_IndexError,
+ space.wrap("string index out of range"))
+ raise OperationError(space.w_IndexError, exc)
+ return W_StringObject(w_str.str[w_str.start + ival])
+
+def getitem__StringSlice_Slice(space, w_str, w_slice):
+ w = space.wrap
+ length = w_str.stop - w_str.start
+ start, stop, step, sl = w_slice.indices4(space, length)
+ if sl == 0:
+ str = ""
+ else:
+ s = w_str.str
+ start = w_str.start + start
+ if step == 1:
+ stop = w_str.start + stop
+ assert start >= 0 and stop >= 0
+ return W_StringSliceObject(s, start, stop)
+ else:
+ str = "".join([s[start + i*step] for i in range(sl)])
+ return W_StringObject(str)
+
+def len__StringSlice(space, w_str):
+ return space.wrap(w_str.stop - w_str.start)
+
+
+def str__StringSlice(space, w_str):
+ if type(w_str) is W_StringSliceObject:
+ return w_str
+ return W_StringSliceObject(w_str.str, w_str.start, w_str.stop)
Added: pypy/dist/pypy/objspace/std/test/test_strsliceobject.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/objspace/std/test/test_strsliceobject.py Sun Jun 25 17:51:26 2006
@@ -0,0 +1,79 @@
+import autopath, py
+
+from pypy.objspace.std.model import WITHSTRSLICE
+if not WITHSTRSLICE:
+ py.test.skip("WITHSTRSLICE is not enabled")
+
+
+class AppTestStringObject:
+
+ def test_basic(self):
+ import sys
+ def slice(s): return (s*3)[len(s):-len(s)]
+ s = slice('0123456789')
+ assert len(s) == 10
+ assert s[5] == '5'
+ assert s[-2] == '8'
+ assert s[3:7] == '3456'
+ assert 'W_StringSliceObject' in sys.pypy_repr(s)
+ assert 'W_StringSliceObject' in sys.pypy_repr(s[3:7])
+
+ def test_find(self):
+ def slice(s): return (s*3)[len(s):-len(s)]
+ assert slice('abcdefghiabc').find('abc') == 0
+ assert slice('abcdefghiabc').find('abc', 1) == 9
+ assert slice('abcdefghiabc').find('def', 4) == -1
+
+ def test_index(self):
+ from sys import maxint
+ def slice(s): return (s*3)[len(s):-len(s)]
+ assert slice('abcdefghiabc').index('') == 0
+ assert slice('abcdefghiabc').index('def') == 3
+ assert slice('abcdefghiabc').index('abc') == 0
+ assert slice('abcdefghiabc').index('abc', 1) == 9
+ assert slice('abcdefghiabc').index('def', -4*maxint, 4*maxint) == 3
+ raises(ValueError, slice('abcdefghiabc').index, 'hib')
+ raises(ValueError, slice('abcdefghiab').index, 'abc', 1)
+ raises(ValueError, slice('abcdefghi').index, 'ghi', 8)
+ raises(ValueError, slice('abcdefghi').index, 'ghi', -1)
+ raises(TypeError, slice('abcdefghijklmn').index, 'abc', 0, 0.0)
+ raises(TypeError, slice('abcdefghijklmn').index, 'abc', -10.0, 30)
+
+ def test_rfind(self):
+ def slice(s): return (s*3)[len(s):-len(s)]
+ assert slice('abcdefghiabc').rfind('abc') == 9
+ assert slice('abcdefghiabc').rfind('') == 12
+ assert slice('abcdefghiabc').rfind('abcd') == 0
+ assert slice('abcdefghiabc').rfind('abcz') == -1
+
+ def test_rindex(self):
+ from sys import maxint
+ def slice(s): return (s*3)[len(s):-len(s)]
+ assert slice('abcdefghiabc').rindex('') == 12
+ assert slice('abcdefghiabc').rindex('def') == 3
+ assert slice('abcdefghiabc').rindex('abc') == 9
+ assert slice('abcdefghiabc').rindex('abc', 0, -1) == 0
+ assert slice('abcdefghiabc').rindex('abc', -4*maxint, 4*maxint) == 9
+ raises(ValueError, slice('abcdefghiabc').rindex, 'hib')
+ raises(ValueError, slice('defghiabc').rindex, 'def', 1)
+ raises(ValueError, slice('defghiabc').rindex, 'abc', 0, -1)
+ raises(ValueError, slice('abcdefghi').rindex, 'ghi', 0, 8)
+ raises(ValueError, slice('abcdefghi').rindex, 'ghi', 0, -1)
+ raises(TypeError, slice('abcdefghijklmn').rindex, 'abc', 0, 0.0)
+ raises(TypeError, slice('abcdefghijklmn').rindex, 'abc', -10.0, 30)
+
+ def test_contains(self):
+ def slice(s): return (s*3)[len(s):-len(s)]
+ assert '' in slice('abc')
+ assert 'a' in slice('abc')
+ assert 'ab' in slice('abc')
+ assert not 'd' in slice('abc')
+ raises(TypeError, slice('a').__contains__, 1)
+
+ def test_hash(self):
+ # check that we have the same hash as CPython for at least 31 bits
+ # (but don't go checking CPython's special case -1)
+ # disabled: assert hash('') == 0 --- different special case
+ def slice(s): return (s*3)[len(s):-len(s)]
+ assert hash(slice('hello')) & 0x7fffffff == 0x347697fd
+ assert hash(slice('hello world!')) & 0x7fffffff == 0x2f0bb411
More information about the Pypy-commit
mailing list