Author: Richard Plangger <[email protected]>
Branch: py3.5-memoryview
Changeset: r86746:a64fb8d7c7d8
Date: 2016-08-30 17:35 +0200
http://bitbucket.org/pypy/pypy/changeset/a64fb8d7c7d8/

Log:    lots of details and corner cases to fix memoryview with the new
        attributes, impl. buffer interface for array.array

diff --git a/pypy/module/array/interp_array.py 
b/pypy/module/array/interp_array.py
--- a/pypy/module/array/interp_array.py
+++ b/pypy/module/array/interp_array.py
@@ -636,6 +636,18 @@
     def getlength(self):
         return self.array.len * self.array.itemsize
 
+    def getformat(self):
+        return self.array.typecode
+
+    def getitemsize(self):
+        return self.array.itemsize
+
+    def getndim(self):
+        return 1
+
+    def getstrides(self):
+        return [self.getitemsize()]
+
     def getitem(self, index):
         array = self.array
         data = array._charbuf_start()
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
@@ -132,12 +132,16 @@
 
     def _copy_base(self, data, off):
         shapes = self.getshape()
-        step = shapes[0] // self.getitemsize()
+        step = shapes[0]
         strides = self.getstrides()
+        itemsize = self.getitemsize()
         for i in range(step):
-            bytes = self.buf.getslice(off, off+self.itemsize, 1, self.itemsize)
+            bytes = self.buf.getslice(off, off+itemsize, 1, itemsize)
             data.append(bytes)
             off += strides[0]
+            # do notcopy data if the sub buffer is out of bounds
+            if off >= self.buf.getlength():
+                break
 
     def getlength(self):
         if self.length != -1:
@@ -265,11 +269,9 @@
                 fmtiter = UnpackFormatIterator(space, buf)
                 fmtiter.interpret(self.format)
                 return fmtiter.result_w[0]
-        elif step == 1:
+        elif step >= 1:
             buf = SubBuffer(self.buf, start, size)
-            return W_MemoryView(buf, self.getformat(), itemsize)
-        else:
-            mv = W_MemoryView.copy(self)
+            mv = W_MemoryView.copy(self, buf)
             mv.slice(start, stop, step, size)
             mv.length = mv.bytecount_from_shape()
             mv._init_flags()
@@ -281,12 +283,11 @@
         # TODO subbuffer
         strides = self.getstrides()[:]
         shape = self.getshape()[:]
-        itemsize = self.itemsize
+        itemsize = self.getitemsize()
         dim = 0
-        length = self.buf.getlength()
-        self.buf = SubBuffer(self.buf, strides[dim] * start, size)
+        self.buf = SubBuffer(self.buf, strides[dim] * (start//itemsize), size 
* itemsize)
         shape[dim] = size
-        strides[dim] = strides[dim] * step * itemsize
+        strides[dim] = strides[dim] * step
         self.strides = strides
         self.shape = shape
 
@@ -299,12 +300,13 @@
         return length * self.getitemsize()
 
     @staticmethod
-    def copy(view):
+    def copy(view, buf=None):
         # TODO suboffsets
-        return W_MemoryView(view.buf, view.getformat(), view.getitemsize(),
+        if buf == None:
+            buf = view.buf
+        return W_MemoryView(buf, view.getformat(), view.getitemsize(),
                             view.getndim(), view.getshape()[:], 
view.getstrides()[:])
 
-
     def _apply_itemsize(self, space, start, size, itemsize):
         if itemsize > 1:
             start *= itemsize
@@ -351,17 +353,21 @@
                 raise oefmt(space.w_NotImplementedError,
                         "memoryview slice assignments are currently "
                         "restricted to ndim = 1")
+            # this is the case of a one dimensional copy!
+            # NOTE we could maybe make use of copy_base, but currently we do 
not
             itemsize = self.getitemsize()
             data = []
             src = space.buffer_w(w_obj, space.BUF_CONTIG_RO)
             dst_strides = self.getstrides()
             dim = 0
-            dst = SubBuffer(self.buf, start + dst_strides[dim] * (start // 
itemsize), self.buf.getlength())
+            dst = SubBuffer(self.buf, start, size)
             src_stride0 = dst_strides[dim]
 
             off = 0
-            src_shape0 = size
+            src_shape0 = size // itemsize
             src_stride0 = src.getstrides()[0]
+            if isinstance(w_obj, W_MemoryView):
+                src_stride0 = w_obj.getstrides()[0]
             for i in range(src_shape0):
                 data.append(src.getslice(off,off+itemsize,1,itemsize))
                 off += src_stride0
@@ -575,8 +581,8 @@
         self.format = newfmt
         self.itemsize = itemsize
         self.ndim = 1
-        self.shape = [buf.getlength() // buf.getitemsize()]
-        self.strides = [buf.getitemsize()]
+        self.shape = [buf.getlength() // itemsize]
+        self.strides = [itemsize]
         # XX suboffsets
 
         self._init_flags()
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
@@ -225,7 +225,7 @@
         data = bytearray(b'abcdefghij')
         m3 = memoryview(data).cast('h')
         m3[1:5:2] = memoryview(b"xyXY").cast('h')
-        assert data == bytearray(b'abxyefXYij')
+        assert data == bytearray(eval("b'abxyefXYij'"))
 
 class MockBuffer(Buffer):
     def __init__(self, space, w_arr, w_dim, w_fmt, \
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to