[pypy-commit] pypy refactor-buffer-api: clean up buffer/memoryview setitem
bdkearns
noreply at buildbot.pypy.org
Thu Apr 24 09:40:33 CEST 2014
Author: Brian Kearns <bdkearns at gmail.com>
Branch: refactor-buffer-api
Changeset: r70920:fc458f88faff
Date: 2014-04-24 01:44 -0400
http://bitbucket.org/pypy/pypy/changeset/fc458f88faff/
Log: clean up buffer/memoryview setitem
diff --git a/pypy/module/__pypy__/test/test_bytebuffer.py b/pypy/module/__pypy__/test/test_bytebuffer.py
--- a/pypy/module/__pypy__/test/test_bytebuffer.py
+++ b/pypy/module/__pypy__/test/test_bytebuffer.py
@@ -13,3 +13,15 @@
assert b[-1] == '*'
assert b[-2] == '-'
assert b[-3] == '+'
+ exc = raises(TypeError, "b[3] = 'abc'")
+ assert str(exc.value) == "right operand must be a single byte"
+ exc = raises(TypeError, "b[3:5] = 'abc'")
+ assert str(exc.value) == "right operand length must match slice length"
+ exc = raises(TypeError, "b[3:7:2] = 'abc'")
+ assert str(exc.value) == "right operand length must match slice length"
+
+ b = bytebuffer(10)
+ b[1:3] = 'xy'
+ assert str(b) == "\x00xy" + "\x00" * 7
+ b[4:8:2] = 'zw'
+ assert str(b) == "\x00xy\x00z\x00w" + "\x00" * 3
diff --git a/pypy/objspace/std/bufferobject.py b/pypy/objspace/std/bufferobject.py
--- a/pypy/objspace/std/bufferobject.py
+++ b/pypy/objspace/std/bufferobject.py
@@ -10,7 +10,6 @@
from pypy.interpreter.typedef import TypeDef
from rpython.rlib.objectmodel import compute_hash
from rpython.rlib.rstring import StringBuilder
-from pypy.objspace.std.memoryobject import _buffer_setitem
class W_Buffer(W_Root):
@@ -71,12 +70,26 @@
res = self.buf.getslice(start, stop, step, size)
return space.wrap(res)
- @unwrap_spec(newstring='bufferstr')
- def descr_setitem(self, space, w_index, newstring):
+ def descr_setitem(self, space, w_index, w_obj):
if not self.buf.is_writable():
raise OperationError(space.w_TypeError,
space.wrap("buffer is read-only"))
- _buffer_setitem(space, self.buf, w_index, newstring)
+ start, stop, step, size = space.decode_index4(w_index, self.buf.getlength())
+ value = space.readbuf_w(w_obj)
+ if step == 0: # index only
+ if value.getlength() != 1:
+ msg = "right operand must be a single byte"
+ raise OperationError(space.w_TypeError, space.wrap(msg))
+ self.buf.setitem(start, value.getitem(0))
+ else:
+ if value.getlength() != size:
+ msg = "right operand length must match slice length"
+ raise OperationError(space.w_TypeError, space.wrap(msg))
+ if step == 1:
+ self.buf.setslice(start, value.as_str())
+ else:
+ for i in range(size):
+ self.buf.setitem(start + i * step, value.getitem(i))
def descr_str(self, space):
return space.wrap(self.buf.as_str())
diff --git a/pypy/objspace/std/memoryobject.py b/pypy/objspace/std/memoryobject.py
--- a/pypy/objspace/std/memoryobject.py
+++ b/pypy/objspace/std/memoryobject.py
@@ -10,25 +10,6 @@
from pypy.interpreter.typedef import TypeDef, GetSetProperty
-def _buffer_setitem(space, buf, w_index, newstring):
- start, stop, step, size = space.decode_index4(w_index, buf.getlength())
- if step == 0: # index only
- if len(newstring) != 1:
- msg = 'buffer[index]=x: x must be a single character'
- raise OperationError(space.w_TypeError, space.wrap(msg))
- char = newstring[0] # annotator hint
- buf.setitem(start, char)
- elif step == 1:
- if len(newstring) != size:
- msg = "right operand length must match slice length"
- raise OperationError(space.w_ValueError, space.wrap(msg))
- buf.setslice(start, newstring)
- else:
- raise OperationError(space.w_ValueError,
- space.wrap("buffer object does not support"
- " slicing with a step"))
-
-
class W_MemoryView(W_Root):
"""Implement the built-in 'memoryview' type as a wrapper around
an interp-level buffer.
@@ -40,7 +21,8 @@
self.buf = buf
def buffer_w(self, space, flags):
- return space.buffer_w(self.obj, flags)
+ space.check_buf_flags(flags, self.buf.readonly)
+ return self.buf
@staticmethod
def descr_new_memoryview(space, w_subtype, w_object):
@@ -101,22 +83,28 @@
def descr_getitem(self, space, w_index):
start, stop, step = space.decode_index(w_index, self.getlength())
+ if step not in (0, 1):
+ raise OperationError(space.w_NotImplementedError, space.wrap(""))
if step == 0: # index only
return space.wrap(self.buf.getitem(start))
+ res = self.getslice(start, stop)
+ return space.wrap(res)
+
+ def descr_setitem(self, space, w_index, w_obj):
+ if not self.buf.is_writable():
+ raise OperationError(space.w_TypeError, space.wrap(
+ "cannot modify read-only memory"))
+ start, stop, step, size = space.decode_index4(w_index, self.buf.getlength())
+ if step not in (0, 1):
+ raise OperationError(space.w_NotImplementedError, space.wrap(""))
+ value = space.buffer_w(w_obj, space.BUF_CONTIG_RO)
+ if value.getlength() != size:
+ raise OperationError(space.w_ValueError, space.wrap(
+ "cannot modify size of memoryview object"))
+ if step == 0: # index only
+ self.buf.setitem(start, value.getitem(0))
elif step == 1:
- res = self.getslice(start, stop)
- return space.wrap(res)
- else:
- raise OperationError(space.w_ValueError,
- space.wrap("memoryview object does not support"
- " slicing with a step"))
-
- @unwrap_spec(newstring='bufferstr')
- def descr_setitem(self, space, w_index, newstring):
- if not self.buf.is_writable():
- raise OperationError(space.w_TypeError,
- space.wrap("cannot modify read-only memory"))
- _buffer_setitem(space, self.buf, w_index, newstring)
+ self.buf.setslice(start, value.as_str())
def descr_len(self, space):
return space.wrap(self.buf.getlength())
diff --git a/pypy/objspace/std/test/test_memoryobject.py b/pypy/objspace/std/test/test_memoryobject.py
--- a/pypy/objspace/std/test/test_memoryobject.py
+++ b/pypy/objspace/std/test/test_memoryobject.py
@@ -7,11 +7,14 @@
assert v.tolist() == [97, 98, 99]
assert v[1] == "b"
assert v[-1] == "c"
- raises(TypeError, "v[1] = 'x'")
+ exc = raises(TypeError, "v[1] = 'x'")
+ assert str(exc.value) == "cannot modify read-only memory"
assert v.readonly is True
w = v[1:234]
assert isinstance(w, memoryview)
assert len(w) == 2
+ exc = raises(NotImplementedError, "v[0:2:2]")
+ assert str(exc.value) == ""
def test_rw(self):
data = bytearray('abcefg')
@@ -21,7 +24,12 @@
assert data == bytearray(eval("b'zbcefg'"))
v[1:4] = '123'
assert data == bytearray(eval("b'z123fg'"))
- raises((ValueError, TypeError), "v[2] = 'spam'")
+ v[0:3] = v[2:5]
+ assert data == bytearray(eval("b'23f3fg'"))
+ exc = raises(ValueError, "v[2] = 'spam'")
+ assert str(exc.value) == "cannot modify size of memoryview object"
+ exc = raises(NotImplementedError, "v[0:2:2] = 'spam'")
+ assert str(exc.value) == ""
def test_memoryview_attrs(self):
v = memoryview("a"*100)
More information about the pypy-commit
mailing list