[pypy-commit] pypy py3.5-memoryview: working on memoryview cast. some of that logic should move the the rlib buffer
plan_rich
pypy.commits at gmail.com
Fri Aug 26 08:15:49 EDT 2016
Author: Richard Plangger <planrichi at gmail.com>
Branch: py3.5-memoryview
Changeset: r86551:5053ecabfdc0
Date: 2016-08-26 14:15 +0200
http://bitbucket.org/pypy/pypy/changeset/5053ecabfdc0/
Log: working on memoryview cast. some of that logic should move the the
rlib buffer
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
@@ -309,6 +309,7 @@
return size
def _zero_in_shape(self):
+ # TODO move to buffer
view = self.buf
shape = view.shape
for i in range(view.ndim):
@@ -320,23 +321,25 @@
# XXX fixme. does not do anything near cpython (see memoryobjet.c memory_cast)
self._check_released(space)
- if not space.isinstance_w(w_obj, space.w_unicode):
+ if not space.isinstance_w(w_format, space.w_unicode):
raise OperationError(space.w_TypeError, \
space.wrap("memoryview: format argument must be a string"))
- buf = self.buf
+ fmt = space.str_w(w_format)
+ view = self.buf
ndim = 1
- if not memory_view_c_contiguous(buf.flags):
+ if not memory_view_c_contiguous(space, view.flags):
raise OperationError(space.w_TypeError, \
space.wrap("memoryview: casts are restricted" \
" to C-contiguous views"))
- if (w_shape or buf.ndim != 1) and self._zero_in_shape():
+ if (w_shape or view.getndim() != 1) and self._zero_in_shape():
raise OperationError(space.w_TypeError, \
space.wrap("memoryview: cannot casts view with" \
" zeros in shape or strides"))
+ itemsize = self.get_native_fmtchar(fmt)
if w_shape:
if not (space.is_w(w_obj, space.w_list) or space.is_w(w_obj, space.w_tuple)):
raise oefmt(space.w_TypeError, "expected list or tuple got %T", w_obj)
@@ -349,19 +352,13 @@
raise OperationError(space.w_TypeError, \
space.wrap("memoryview: cast must be 1D -> ND or ND -> 1D"))
- mv = W_MemoryView(self.buf)
- mv._init_shared_values(space, self)
- mv.itemsize = self.get_native_fmtchar(fmt)
+ shape = [space.int_w(w_obj) for w_obj in w_shape.fixedview_unroll()]
+ return W_MemoryView(Buffer.cast_to(buf, itemsize, shape))
- if not mv._cast_to_1D(space, fmt):
- return space.w_None
- if w_shape is not space.w_None:
- shape = space.fixedview(w_shape)
- if not mv._cast_to_ND(space, shape, ndim):
- return space.w_None
- return mv
+ return W_MemoryView(Buffer.cast_to(buf, itemsize, None))
def _init_flags(self):
+ # TODO move to buffer.py
view = self.buf
ndim = view.ndim
flags = 0
@@ -381,30 +378,31 @@
def _cast_to_1D(self, space, fmt):
itemsize = self.get_native_fmtchar(fmt)
- view = self.buf
+ buf = self.buf
if itemsize < 0:
raise OperationError(space.w_ValueError, "memoryview: destination" \
" format must be a native single character format prefixed" \
" with an optional '@'")
- if self.get_native_fmtchar(view.format) < 0 or \
- (not is_byte_format(fmt) and not is_byte_format(view.format)):
+ buffmt = buf.getformat()
+ if self.get_native_fmtchar(buffmt) < 0 or \
+ (not is_byte_format(fmt) and not is_byte_format(buffmt)):
raise OperationError(space.w_TypeError,
"memoryview: cannot cast between" \
" two non-byte formats")
- if view.length % itemsize != 0:
+ if buf.getlength() % itemsize != 0:
raise OperationError(space.w_TypeError,
"memoryview: length is not a multiple of itemsize")
- view.format = get_native_fmtstr(fmt)
- if not view.format:
+ buf.format = get_native_fmtstr(fmt)
+ if not buffmt:
raise OperationError(space.w_RuntimeError,
"memoryview: internal error")
- view.itemsize = itemsize
- view.ndim = 1
- view.shape[0] = view.length / view.itemsize
- view.srides[0] = view.itemsize
+ buf.itemsize = itemsize
+ buf.ndim = 1
+ buf.shape[0] = buf.length / buf.itemsize
+ buf.srides[0] = buf.itemsize
# XX suboffsets
mv._init_flags()
@@ -412,13 +410,6 @@
def _cast_to_ND(self, space, shape, ndim):
pass
- def _init_shared_values(self, space, of):
- mv.buf = buf # XXX not quite right
- mv.format = of.format
- mv.readonly = of.readonly
- mv.itemsize = of.itemsize
- return mv
-
def descr_hex(self, space):
from pypy.objspace.std.bytearrayobject import _array_to_hexstring
self._check_released(space)
@@ -427,8 +418,8 @@
def is_byte_format(char):
return char == 'b' or char == 'B' or char == 'c'
-def memory_view_c_contiguous(flags):
- return flags & (space.BUF_CONTIG_RO|space.BUF_C) != 0
+def memory_view_c_contiguous(space, flags):
+ return flags & (space.BUF_CONTIG_RO|space.MEMORYVIEW_C) != 0
W_MemoryView.typedef = TypeDef(
"memoryview",
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
@@ -177,6 +177,7 @@
def __init__(self, space, w_arr, w_dim, w_fmt, \
w_itemsize, w_strides, w_shape):
self.space = space
+ self.flags = space.MEMORYVIEW_C
self.w_arr = w_arr
self.arr = []
self.ndim = space.int_w(w_dim)
@@ -294,3 +295,9 @@
assert view[0,0,0] == 1
assert view[-1,2,0] == 6
+ def test_cast_empty(self):
+ empty = self.MockArray([], dim=1, fmt='i', size=4, strides=[1], shape=[1])
+ view = memoryview(empty)
+ cview = view.cast('i')
+ assert cview.tobytes() == b''
+
More information about the pypy-commit
mailing list