Author: Brian Kearns <bdkea...@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) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit