[pypy-commit] pypy PyBuffer: Don't mutate the memoryview in _cast_to_1D()

rlamy pypy.commits at gmail.com
Tue Mar 28 09:14:50 EDT 2017


Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: PyBuffer
Changeset: r90839:cd13570ce008
Date: 2017-03-28 02:25 +0100
http://bitbucket.org/pypy/pypy/changeset/cd13570ce008/

Log:	Don't mutate the memoryview in _cast_to_1D()

diff --git a/pypy/interpreter/buffer.py b/pypy/interpreter/buffer.py
--- a/pypy/interpreter/buffer.py
+++ b/pypy/interpreter/buffer.py
@@ -123,6 +123,50 @@
     def getstrides(self):
         return [1]
 
+class BufferView1D(Buffer):
+    def __init__(self, data, format, itemsize):
+        self.data = data
+        self.readonly = data.readonly
+        self.format = format
+        self.itemsize = itemsize
+
+    def getlength(self):
+        return self.data.getlength()
+
+    def as_str(self):
+        return self.data.as_str()
+
+    def as_str_and_offset_maybe(self):
+        return self.data.as_str_and_offset_maybe()
+
+    def getitem(self, index):
+        return self.data.getitem(index)
+
+    def setitem(self, index, value):
+        return self.data.setitem(index, value)
+
+    def get_raw_address(self):
+        return self.data.get_raw_address()
+
+    def as_binary(self):
+        return self.data
+
+    def getformat(self):
+        return self.format
+
+    def getitemsize(self):
+        return self.itemsize
+
+    def getndim(self):
+        return 1
+
+    def getshape(self):
+        return [self.getlength() // self.itemsize]
+
+    def getstrides(self):
+        return [self.itemsize]
+
+
 class BinaryBuffer(Buffer):
     """Base class for buffers of bytes"""
     _attrs_ = ['readonly']
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
@@ -6,7 +6,7 @@
 from rpython.rlib.objectmodel import compute_hash
 from rpython.rlib.rstruct.error import StructError
 from pypy.interpreter.baseobjspace import W_Root
-from pypy.interpreter.buffer import Buffer, SubBuffer, StringBuffer
+from pypy.interpreter.buffer import Buffer, SubBuffer, StringBuffer, BufferView1D
 from pypy.interpreter.error import OperationError, oefmt
 from pypy.interpreter.gateway import interp2app
 from pypy.interpreter.typedef import TypeDef, GetSetProperty,  make_weakref_descr
@@ -543,7 +543,6 @@
                         "memoryview: cannot casts view with"
                         " zeros in shape or strides")
 
-        itemsize = self.get_native_fmtchar(fmt)
         if w_shape:
             if not (space.isinstance_w(w_shape, space.w_list) or space.isinstance_w(w_shape, space.w_tuple)):
                 raise oefmt(space.w_TypeError, "expected list or tuple got %T", w_shape)
@@ -557,7 +556,7 @@
                             "memoryview: cast must be 1D -> ND or ND -> 1D")
 
         origfmt = self.getformat()
-        mv = self._cast_to_1D(space, buf, origfmt, fmt, itemsize)
+        mv = self._cast_to_1D(space, buf, origfmt, fmt)
         if w_shape:
             fview = space.fixedview(w_shape)
             shape = [space.int_w(w_obj) for w_obj in fview]
@@ -594,7 +593,8 @@
 
         self.flags = flags
 
-    def _cast_to_1D(self, space, buf, origfmt, fmt, itemsize):
+    def _cast_to_1D(self, space, buf, origfmt, fmt):
+        itemsize = self.get_native_fmtchar(fmt)
         if itemsize < 0:
             raise oefmt(space.w_ValueError, "memoryview: destination" \
                     " format must be a native single character format prefixed" \
@@ -614,12 +614,8 @@
         if not newfmt:
             raise oefmt(space.w_RuntimeError,
                     "memoryview: internal error")
-        mv = W_MemoryView(buf, newfmt, itemsize)
-        mv.ndim = 1
-        mv.shape = [buf.getlength() // itemsize]
-        mv.strides = [itemsize]
-        # XX suboffsets
-
+        newbuf = BufferView1D(buf, newfmt, itemsize)
+        mv = W_MemoryView(newbuf, newbuf.getformat(), newbuf.getitemsize())
         mv._init_flags()
         return mv
 
@@ -682,7 +678,7 @@
     def descr_hex(self, space):
         from pypy.objspace.std.bytearrayobject import _array_to_hexstring
         self._check_released(space)
-        return _array_to_hexstring(space, self.buf.as_binary(), 0, 1, self.getlength())
+        return _array_to_hexstring(space, self.buf, 0, 1, self.getlength())
 
 def is_byte_format(char):
     return char == 'b' or char == 'B' or char == 'c'


More information about the pypy-commit mailing list