Author: Ronan Lamy <ronan.l...@gmail.com> Branch: PyBuffer Changeset: r91095:e30a5a8a4062 Date: 2017-04-19 19:44 +0100 http://bitbucket.org/pypy/pypy/changeset/e30a5a8a4062/
Log: Fix interaction of space.getarg_w('w*', ...) and CPyBuffer diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1540,7 +1540,7 @@ self._getarg_error("bytes or read-only buffer", w_obj) elif code == 'w*': try: - return w_obj.buffer_w(self, self.BUF_WRITABLE).as_binary() + return w_obj.buffer_w(self, self.BUF_WRITABLE).as_binary_rw() except OperationError: pass except BufferInterfaceNotFound: diff --git a/pypy/interpreter/buffer.py b/pypy/interpreter/buffer.py --- a/pypy/interpreter/buffer.py +++ b/pypy/interpreter/buffer.py @@ -39,6 +39,10 @@ # Inefficient. May be overridden. return StringBuffer(self.as_str()) + def as_binary_rw(self): + """Return a writable BinaryBuffer sharing the same data as `self`.""" + raise NotImplementedError + def getformat(self): raise NotImplementedError @@ -204,6 +208,10 @@ def as_binary(self): return self.data + def as_binary_rw(self): + assert not self.data.readonly + return self.data + def getformat(self): return 'B' diff --git a/pypy/module/cpyext/slotdefs.py b/pypy/module/cpyext/slotdefs.py --- a/pypy/module/cpyext/slotdefs.py +++ b/pypy/module/cpyext/slotdefs.py @@ -19,7 +19,7 @@ from pypy.module.cpyext.memoryobject import fill_Py_buffer from pypy.module.cpyext.state import State from pypy.module.cpyext import userslot -from pypy.interpreter.buffer import PyBuffer +from pypy.interpreter.buffer import PyBuffer, BinaryBuffer from pypy.interpreter.error import OperationError, oefmt from pypy.interpreter.argument import Arguments from rpython.rlib.unroll import unrolling_iterable @@ -388,6 +388,13 @@ for i in range(len(string)): self.ptr[start + i] = string[i] + def as_binary(self): + return CBuffer(self) + + def as_binary_rw(self): + assert not self.readonly + return CBuffer(self) + def get_raw_address(self): return rffi.cast(rffi.CCHARP, self.ptr) @@ -417,6 +424,37 @@ fq = FQ() + +class CBuffer(BinaryBuffer): + _immutable_ = True + def __init__(self, pybuffer): + self.pybuffer = pybuffer + self.readonly = pybuffer.readonly + + def getlength(self): + return self.pybuffer.getlength() + + def getitem(self, index): + return self.pybuffer.ptr[index] + + def getslice(self, start, stop, step, size): + assert step == 1 + assert stop - start == size + ptr = rffi.ptradd(cts.cast('char *', self.pybuffer.ptr), start) + return rffi.charpsize2str(ptr, size) + + def setitem(self, index, char): + self.pybuffer.ptr[index] = char + + def setslice(self, index, s): + assert s is not None + ptr = rffi.ptradd(cts.cast('char *', self.pybuffer.ptr), index) + rffi.str2chararray(s, ptr, len(s)) + + def get_raw_address(self): + return cts.cast('char *', self.pybuffer.ptr) + + def wrap_getreadbuffer(space, w_self, w_args, func): func_target = rffi.cast(readbufferproc, func) py_obj = make_ref(space, w_self) 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 @@ -216,7 +216,9 @@ src = space.buffer_w(w_obj, space.BUF_CONTIG_RO) dst_strides = self.getstrides() dim = 0 - dst = SubBuffer(self.buf.as_binary(), start * itemsize, slicelength * itemsize) + dst = SubBuffer( + self.buf.as_binary_rw(), + start * itemsize, slicelength * itemsize) src_stride0 = dst_strides[dim] off = 0 @@ -670,6 +672,9 @@ def as_binary(self): return self.parent.as_binary() + def as_binary_rw(self): + return self.parent.as_binary_rw() + class BufferView1D(BufferViewBase): _immutable_ = True _attrs_ = ['readonly', 'parent', 'format', 'itemsize'] _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit