Author: Ronan Lamy <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit