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