[pypy-svn] pypy fast-forward: Implemented extended slicing for buffers.
alex_gaynor
commits-noreply at bitbucket.org
Sat Jan 8 09:34:45 CET 2011
Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: fast-forward
Changeset: r40479:e8e6655da29d
Date: 2011-01-08 02:34 -0600
http://bitbucket.org/pypy/pypy/changeset/e8e6655da29d/
Log: Implemented extended slicing for buffers.
diff --git a/pypy/module/__builtin__/test/test_buffer.py b/pypy/module/__builtin__/test/test_buffer.py
--- a/pypy/module/__builtin__/test/test_buffer.py
+++ b/pypy/module/__builtin__/test/test_buffer.py
@@ -160,6 +160,17 @@
raises(ValueError, buffer, a, -1)
raises(ValueError, buffer, a, 0, -2)
+ def test_slice(self):
+ # Test extended slicing by comparing with list slicing.
+ s = "".join(chr(c) for c in list(range(255, -1, -1)))
+ b = buffer(s)
+ indices = (0, None, 1, 3, 19, 300, -1, -2, -31, -300)
+ for start in indices:
+ for stop in indices:
+ # Skip step 0 (invalid)
+ for step in indices[1:]:
+ assert b[start:stop:step] == s[start:stop:step]
+
class AppTestMemoryView:
def test_basic(self):
v = memoryview("abc")
diff --git a/pypy/interpreter/buffer.py b/pypy/interpreter/buffer.py
--- a/pypy/interpreter/buffer.py
+++ b/pypy/interpreter/buffer.py
@@ -33,15 +33,15 @@
def as_str(self):
"Returns an interp-level string with the whole content of the buffer."
# May be overridden.
- return self.getslice(0, self.getlength())
+ return self.getslice(0, self.getlength(), 1, self.getlength())
def getitem(self, index):
"Returns the index'th character in the buffer."
raise NotImplementedError # Must be overriden. No bounds checks.
- def getslice(self, start, stop):
+ def getslice(self, start, stop, step, size):
# May be overridden. No bounds checks.
- return ''.join([self.getitem(i) for i in range(start, stop)])
+ return ''.join([self.getitem(i) for i in range(start, stop, step)])
# __________ app-level support __________
@@ -50,16 +50,11 @@
descr_len.unwrap_spec = ['self', ObjSpace]
def descr_getitem(self, space, w_index):
- start, stop, step = space.decode_index(w_index, self.getlength())
+ start, stop, step, size = space.decode_index4(w_index, self.getlength())
if step == 0: # index only
return space.wrap(self.getitem(start))
- elif step == 1:
- res = self.getslice(start, stop)
- return space.wrap(res)
- else:
- raise OperationError(space.w_ValueError,
- space.wrap("buffer object does not support"
- " slicing with a step"))
+ res = self.getslice(start, stop, step, size)
+ return space.wrap(res)
descr_getitem.unwrap_spec = ['self', ObjSpace, W_Root]
def descr_setitem(self, space, w_index, newstring):
@@ -135,7 +130,7 @@
else:
info = 'read-only buffer'
addrstring = self.getaddrstring(space)
-
+
return space.wrap("<%s for 0x%s, size %d>" %
(info, addrstring, self.getlength()))
descr_repr.unwrap_spec = ['self', ObjSpace]
@@ -226,9 +221,10 @@
def getitem(self, index):
return self.value[index]
- def getslice(self, start, stop):
- assert 0 <= start <= stop <= len(self.value)
- return self.value[start:stop]
+ def getslice(self, start, stop, step, size):
+ if step == 1:
+ return self.value[start:stop]
+ return "".join([self.value[start + i*step] for i in xrange(size)])
class StringLikeBuffer(Buffer):
@@ -282,11 +278,11 @@
def getitem(self, index):
return self.buffer.getitem(self.offset + index)
- def getslice(self, start, stop):
+ def getslice(self, start, stop, step, size):
if start == stop:
return '' # otherwise, adding self.offset might make them
# out of bounds
- return self.buffer.getslice(self.offset + start, self.offset + stop)
+ return self.buffer.getslice(self.offset + start, self.offset + stop, step, size)
class SubBuffer(SubBufferMixin, Buffer):
pass
More information about the Pypy-commit
mailing list