[pypy-commit] pypy py3.5-ssl: several changes to the memoryview object to pass the tests, most of the problems were related to wrong index calculations
plan_rich
pypy.commits at gmail.com
Wed Dec 7 05:48:19 EST 2016
Author: Richard Plangger <planrichi at gmail.com>
Branch: py3.5-ssl
Changeset: r88930:c9097583272c
Date: 2016-12-07 11:47 +0100
http://bitbucket.org/pypy/pypy/changeset/c9097583272c/
Log: several changes to the memoryview object to pass the tests, most of
the problems were related to wrong index calculations
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
@@ -115,8 +115,6 @@
return ''.join(self.copy_buffer())
def copy_buffer(self):
- buf = self.buf
- n_bytes = buf.getlength()
data = []
self._copy_rec(0, data, 0)
return data
@@ -130,7 +128,6 @@
self._copy_base(data,off)
return
- # TODO add a test that has at least 2 dims
for i in range(shape):
self._copy_rec(idim+1,data,off)
off += strides[idim]
@@ -140,18 +137,21 @@
step = shapes[0]
strides = self.getstrides()
itemsize = self.getitemsize()
+ bytesize = self.getlength()
+ copiedbytes = 0
for i in range(step):
bytes = self.buf.getslice(off, off+itemsize, 1, itemsize)
data.append(bytes)
+ copiedbytes += len(bytes)
off += strides[0]
# do notcopy data if the sub buffer is out of bounds
- if off >= self.buf.getlength():
+ if copiedbytes >= bytesize:
break
def getlength(self):
if self.length != -1:
- return self.length // self.itemsize
- return self.buf.getlength() // self.itemsize
+ return self.length
+ return self.buf.getlength()
def descr_tobytes(self, space):
self._check_released(space)
@@ -198,8 +198,9 @@
return self._tolist(space, buf, bytecount, itemsize, fmt, [stride])
items = [None] * dimshape
+ orig_buf = buf
for i in range(dimshape):
- buf = SubBuffer(buf, start, stride)
+ buf = SubBuffer(orig_buf, start, stride)
item = self._tolist_rec(space, buf, start, idim+1, fmt)
items[i] = item
start += stride
@@ -232,9 +233,8 @@
if index < 0 or index >= nitems:
raise oefmt(space.w_IndexError,
"index out of bounds on dimension %d", dim+1)
- start += strides[dim] * index
# TODO suboffsets?
- return start
+ return start + strides[dim] * index
def _getitem_tuple_indexed(self, space, w_index):
view = self.buf
@@ -259,54 +259,60 @@
fmtiter.interpret(fmt)
return fmtiter.result_w[0]
+ def _decode_index(self, space, w_index, is_slice):
+ shape = self.getshape()
+ if len(shape) == 0:
+ count = 1
+ else:
+ count = shape[0]
+ return space.decode_index4(w_index, count)
def descr_getitem(self, space, w_index):
self._check_released(space)
if space.isinstance_w(w_index, space.w_tuple):
return self._getitem_tuple_indexed(space, w_index)
-
- shape = self.getshape()
- start, stop, step, slicelength = space.decode_index4(w_index, shape[0])
+ is_slice = space.isinstance_w(w_index, space.w_slice)
+ start, stop, step, slicelength = self._decode_index(space, w_index, is_slice)
# ^^^ for a non-slice index, this returns (index, 0, 0, 1)
if step == 0: # index only
itemsize = self.getitemsize()
dim = self.getndim()
- if itemsize == 1:
- if dim == 0:
- raise oefmt(space.w_TypeError, "invalid indexing of 0-dim memory")
- elif dim == 1:
- idx = self.lookup_dimension(space, self, 0, 0, start)
+ if dim == 0:
+ raise oefmt(space.w_TypeError, "invalid indexing of 0-dim memory")
+ elif dim == 1:
+ idx = self.lookup_dimension(space, self, 0, 0, start)
+ if itemsize == 1:
ch = self.buf.getitem(idx)
return space.newint(ord(ch))
else:
- raise oefmt(space.w_NotImplementedError, "multi-dimensional sub-views are not implemented")
+ # TODO: this probably isn't very fast
+ buf = SubBuffer(self.buf, idx, itemsize)
+ fmtiter = UnpackFormatIterator(space, buf)
+ fmtiter.length = buf.getlength()
+ fmtiter.interpret(self.format)
+ return fmtiter.result_w[0]
else:
- # TODO: this probably isn't very fast
- buf = SubBuffer(self.buf, start*itemsize, itemsize)
- fmtiter = UnpackFormatIterator(space, buf)
- fmtiter.interpret(self.format)
- return fmtiter.result_w[0]
- elif step == 1:
- mv = W_MemoryView.copy(self)
- mv.init_slice(start, stop, step, slicelength, 0)
- mv._init_flags()
- return mv
- else:
+ raise oefmt(space.w_NotImplementedError, "multi-dimensional sub-views are not implemented")
+ elif is_slice:
mv = W_MemoryView.copy(self)
mv.init_slice(start, stop, step, slicelength, 0)
mv.init_len()
mv._init_flags()
return mv
+ # multi index is handled at the top of this function
+ else:
+ raise TypeError("memoryview: invalid slice key")
def init_slice(self, start, stop, step, slicelength, dim):
# modifies the buffer, shape and stride to allow step to be > 1
- # TODO subbuffer
self.strides = strides = self.getstrides()[:]
self.shape = shape = self.getshape()[:]
- self.buf = SubBuffer(self.buf, strides[dim] * start, slicelength)
+ bytesize = self.getitemsize() * slicelength
+ self.buf = SubBuffer(self.buf, strides[dim] * start, bytesize)
shape[dim] = slicelength
strides[dim] = strides[dim] * step
+ # TODO subbuffer
def init_len(self):
self.length = self.bytecount_from_shape()
@@ -334,6 +340,8 @@
if space.isinstance_w(w_index, space.w_tuple):
raise oefmt(space.w_NotImplementedError, "")
start, stop, step, size = space.decode_index4(w_index, self.getlength())
+ is_slice = space.isinstance_w(w_index, space.w_slice)
+ start, stop, step, slicelength = self._decode_index(space, w_index, is_slice)
itemsize = self.getitemsize()
if step == 0: # index only
if itemsize == 1:
@@ -351,7 +359,7 @@
self.buf.setslice(start * itemsize, fmtiter.result.build())
elif step == 1:
value = space.buffer_w(w_obj, space.BUF_CONTIG_RO)
- if value.getlength() != size * itemsize:
+ if value.getlength() != slicelength * itemsize:
raise oefmt(space.w_ValueError,
"cannot modify size of memoryview object")
self.buf.setslice(start * itemsize, value.as_str())
@@ -367,11 +375,11 @@
src = space.buffer_w(w_obj, space.BUF_CONTIG_RO)
dst_strides = self.getstrides()
dim = 0
- dst = SubBuffer(self.buf, start * itemsize, size * itemsize)
+ dst = SubBuffer(self.buf, start * itemsize, slicelength * itemsize)
src_stride0 = dst_strides[dim]
off = 0
- src_shape0 = size
+ src_shape0 = slicelength
src_stride0 = src.getstrides()[0]
if isinstance(w_obj, W_MemoryView):
src_stride0 = w_obj.getstrides()[0]
@@ -386,11 +394,15 @@
def descr_len(self, space):
self._check_released(space)
- return space.wrap(self.getlength())
+ dim = self.getndim()
+ if dim == 0:
+ return 1
+ shape = self.getshape()
+ return space.wrap(shape[0])
def w_get_nbytes(self, space):
self._check_released(space)
- return space.wrap(self.buf.getlength())
+ return space.wrap(self.getlength())
def w_get_format(self, space):
self._check_released(space)
@@ -398,11 +410,11 @@
def w_get_itemsize(self, space):
self._check_released(space)
- return space.wrap(self.itemsize)
+ return space.wrap(self.getitemsize())
def w_get_ndim(self, space):
self._check_released(space)
- return space.wrap(self.buf.getndim())
+ return space.wrap(self.getndim())
def w_is_readonly(self, space):
self._check_released(space)
@@ -410,13 +422,13 @@
def w_get_shape(self, space):
self._check_released(space)
- if self.buf.getndim() == 0:
+ if self.getndim() == 0:
return space.w_None
return space.newtuple([space.wrap(x) for x in self.getshape()])
def w_get_strides(self, space):
self._check_released(space)
- if self.buf.getndim() == 0:
+ if self.getndim() == 0:
return space.w_None
return space.newtuple([space.wrap(x) for x in self.getstrides()])
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
@@ -43,13 +43,13 @@
def test_extended_slice(self):
data = bytearray(b'abcefg')
v = memoryview(data)
- w = v[0:2:2] # failing for now: NotImplementedError
+ w = v[0:2:2]
assert len(w) == 1
assert list(w) == [97]
v[::2] = b'ABC'
assert data == bytearray(eval("b'AbBeCg'"))
- assert v[::2] == b'ABC'
- assert v[::-2] == b'geb'
+ assert v[::2].tobytes() == b'ABC'
+ assert v[::-2].tobytes() == b'geb'
def test_memoryview_attrs(self):
v = memoryview(b"a"*100)
More information about the pypy-commit
mailing list