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

Reply via email to