[pypy-commit] pypy py3.5-memoryview: extended slicing for descr_getitem, part of the test passes already

plan_rich pypy.commits at gmail.com
Tue Aug 30 08:30:59 EDT 2016


Author: Richard Plangger <planrichi at gmail.com>
Branch: py3.5-memoryview
Changeset: r86733:fac0fa3c82c0
Date: 2016-08-30 13:35 +0200
http://bitbucket.org/pypy/pypy/changeset/fac0fa3c82c0/

Log:	extended slicing for descr_getitem, part of the test passes already

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
@@ -40,6 +40,7 @@
         self.suboffsets = suboffsets
         self.ndim = ndim
         self.flags = 0
+        self.length = -1
         self._init_flags()
 
     # several fields are "overwritten" by the memory view (shape, strides, ...)
@@ -113,6 +114,8 @@
         return buf.getslice(0, n_bytes, 1, n_bytes)
 
     def getlength(self):
+        if self.length != -1:
+            return self.length // self.itemsize
         return self.buf.getlength() // self.itemsize
 
     def descr_tobytes(self, space):
@@ -240,10 +243,40 @@
             buf = SubBuffer(self.buf, start, size)
             return W_MemoryView(buf, self.getformat(), itemsize)
         else:
-            # XXX needs to return a W_MemoryView with a NonContiguousSubBuffer
-            # maybe?  Need to check the cpyext requirements for that
-            raise oefmt(space.w_NotImplementedError,
-                        "XXX extended slicing")
+            mv = W_MemoryView.copy(self)
+            mv.slice(start, stop, step, size)
+            mv.length = mv.bytecount_from_shape()
+            mv._init_flags()
+            return mv
+
+    def slice(self, start, stop, step, size):
+        # modifies the buffer, shape and stride to allow step to be > 1
+        # NOTE that start, stop, are already bytes
+        # TODO subbuffer
+        strides = self.getstrides()[:]
+        shape = self.getshape()[:]
+        itemsize = self.itemsize
+        dim = 0
+        self.buf = SubBuffer(self.buf, start + strides[dim] * (start // itemsize), self.buf.getlength())
+        shape[dim] = size
+        strides[dim] = strides[dim] * step
+        self.strides = strides
+        self.shape = shape
+
+    def bytecount_from_shape(self):
+        dim = self.getndim()
+        shape = self.getshape()
+        length = 1
+        for i in range(dim):
+            length *= shape[i]
+        return length * self.getitemsize()
+
+    @staticmethod
+    def copy(view):
+        # TODO suboffsets
+        return W_MemoryView(view.buf, view.getformat(), view.getitemsize(),
+                            view.getndim(), view.getshape()[:], view.getstrides()[:])
+
 
     def _apply_itemsize(self, space, start, size, itemsize):
         if itemsize > 1:
@@ -466,7 +499,7 @@
         # TODO elif buf.is_contiguous('F'):
         # TODO     flags |= MEMORYVIEW_FORTRAN
 
-        # XXX missing suboffsets
+        # TODO missing suboffsets
 
         self.flags = flags
 


More information about the pypy-commit mailing list