Author: Matti Picus <[email protected]>
Branch: buffer-interface
Changeset: r86842:04da0bbd16eb
Date: 2016-09-02 18:26 +0300
http://bitbucket.org/pypy/pypy/changeset/04da0bbd16eb/
Log: add all the logic needed to make the tests pass, fixes for
translation
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -1428,6 +1428,9 @@
BUF_FORMAT = 0x0004
BUF_ND = 0x0008
BUF_STRIDES = 0x0010 | BUF_ND
+ BUF_C_CONTIGUOUS = 0x0020 | BUF_STRIDES
+ BUF_F_CONTIGUOUS = 0x0040 | BUF_STRIDES
+ BUF_ANY_CONTIGUOUS = 0x0080 | BUF_STRIDES
BUF_INDIRECT = 0x0100 | BUF_STRIDES
BUF_CONTIG_RO = BUF_ND
diff --git a/pypy/module/cpyext/buffer.py b/pypy/module/cpyext/buffer.py
--- a/pypy/module/cpyext/buffer.py
+++ b/pypy/module/cpyext/buffer.py
@@ -1,5 +1,6 @@
from pypy.interpreter.error import oefmt
from rpython.rtyper.lltypesystem import rffi, lltype
+from rpython.rlib.rarithmetic import widen
from pypy.module.cpyext.api import (
cpython_api, CANNOT_FAIL, Py_buffer, Py_TPFLAGS_HAVE_NEWBUFFER,
Py_ssize_tP)
from pypy.module.cpyext.pyobject import PyObject, as_pyobj, incref
@@ -33,7 +34,8 @@
raise an error if the object can't support a simpler view of its memory.
0 is returned on success and -1 on error."""
- buf = space.call_method(w_obj, "__buffer__", space.newint(flags))
+ flags = widen(flags)
+ buf = space.buffer_w(w_obj, flags)
try:
view.c_buf = rffi.cast(rffi.VOIDP, buf.get_raw_address())
except ValueError:
@@ -58,35 +60,37 @@
return 0
def _IsFortranContiguous(view):
- if view.ndim == 0:
+ ndim = widen(view.c_ndim)
+ if ndim == 0:
return 1
- if not view.strides:
- return view.ndim == 1
- sd = view.itemsize
- if view.ndim == 1:
- return view.shape[0] == 1 or sd == view.strides[0]
- for i in range(view.ndim):
- dim = view.shape[i]
+ if not view.c_strides:
+ return ndim == 1
+ sd = view.c_itemsize
+ if ndim == 1:
+ return view.c_shape[0] == 1 or sd == view.c_strides[0]
+ for i in range(view.c_ndim):
+ dim = view.c_shape[i]
if dim == 0:
return 1
- if view.strides[i] != sd:
+ if view.c_strides[i] != sd:
return 0
sd *= dim
return 1
def _IsCContiguous(view):
- if view.ndim == 0:
+ ndim = widen(view.c_ndim)
+ if ndim == 0:
return 1
- if not view.strides:
- return view.ndim == 1
- sd = view.itemsize
- if view.ndim == 1:
- return view.shape[0] == 1 or sd == view.strides[0]
- for i in range(view.ndim-1, -1, -1):
- dim = view.shape[i]
+ if not view.c_strides:
+ return ndim == 1
+ sd = view.c_itemsize
+ if ndim == 1:
+ return view.c_shape[0] == 1 or sd == view.c_strides[0]
+ for i in range(ndim - 1, -1, -1):
+ dim = view.c_shape[i]
if dim == 0:
return 1
- if view.strides[i] != sd:
+ if view.c_strides[i] != sd:
return 0
sd *= dim
return 1
@@ -99,7 +103,7 @@
(fortran is 'A'). Return 0 otherwise."""
# traverse the strides, checking for consistent stride increases from
# right-to-left (c) or left-to-right (fortran). Copied from cpython
- if not view.suboffsets:
+ if not view.c_suboffsets:
return 0
if (fort == 'C'):
return _IsCContiguous(view)
diff --git a/pypy/module/cpyext/test/test_memoryobject.py
b/pypy/module/cpyext/test/test_memoryobject.py
--- a/pypy/module/cpyext/test/test_memoryobject.py
+++ b/pypy/module/cpyext/test/test_memoryobject.py
@@ -35,7 +35,7 @@
# test_export_flags from numpy test_multiarray
raises(ValueError, get_buffer_info, np.arange(5)[::2], ('SIMPLE',))
# test_relaxed_strides from numpy test_multiarray
- arr = np.ones((1, 10))
+ arr = np.zeros((1, 10))
if arr.flags.f_contiguous:
shape, strides = get_buffer_info(arr, ['F_CONTIGUOUS'])
assert strides[0] == 8
diff --git a/pypy/module/micronumpy/concrete.py
b/pypy/module/micronumpy/concrete.py
--- a/pypy/module/micronumpy/concrete.py
+++ b/pypy/module/micronumpy/concrete.py
@@ -378,7 +378,24 @@
keepalive_until_here(self)
def get_buffer(self, space, flags):
- readonly = not bool(flags & space.BUF_WRITABLE)
+ errtype = space.w_ValueError # should be BufferError, numpy does this
instead
+ if ((flags & space.BUF_C_CONTIGUOUS) == space.BUF_C_CONTIGUOUS and
+ not self.flags & NPY.ARRAY_C_CONTIGUOUS):
+ raise oefmt(errtype, "ndarray is not C-contiguous")
+ if ((flags & space.BUF_F_CONTIGUOUS) == space.BUF_F_CONTIGUOUS and
+ not self.flags & NPY.ARRAY_F_CONTIGUOUS):
+ raise oefmt(errtype, "ndarray is not Fortran contiguous")
+ if ((flags & space.BUF_ANY_CONTIGUOUS) == space.BUF_ANY_CONTIGUOUS and
+ not (self.flags & NPY.ARRAY_F_CONTIGUOUS and
+ self.flags & NPY.ARRAY_C_CONTIGUOUS)):
+ raise oefmt(errtype, "ndarray is not contiguous")
+ if ((flags & space.BUF_STRIDES) != space.BUF_STRIDES and
+ not self.flags & NPY.ARRAY_C_CONTIGUOUS):
+ raise oefmt(errtype, "ndarray is not C-contiguous")
+ if ((flags & space.BUF_WRITABLE) == space.BUF_WRITABLE and
+ not self.flags & NPY.ARRAY_WRITEABLE):
+ raise oefmt(errtype, "buffer source array is read-only")
+ readonly = not (flags & space.BUF_WRITABLE) == space.BUF_WRITABLE
return ArrayBuffer(self, readonly)
def astype(self, space, dtype, order, copy=True):
@@ -696,8 +713,7 @@
index + self.impl.start)
def setitem(self, index, v):
- if self.readonly:
- raise oefmt(space.w_BufferError, "cannot write to a readonly
buffer")
+ # XXX what if self.readonly?
raw_storage_setitem(self.impl.storage, index + self.impl.start,
rffi.cast(lltype.Char, v))
diff --git a/pypy/module/micronumpy/ndarray.py
b/pypy/module/micronumpy/ndarray.py
--- a/pypy/module/micronumpy/ndarray.py
+++ b/pypy/module/micronumpy/ndarray.py
@@ -804,8 +804,8 @@
""")
return w_result
- def buffer_w(self, space, w_flags):
- return self.implementation.get_buffer(space, space.int_w(w_flags))
+ def buffer_w(self, space, flags):
+ return self.implementation.get_buffer(space, flags)
def readbuf_w(self, space):
return self.implementation.get_buffer(space, space.BUF_FULL_RO)
@@ -1697,7 +1697,6 @@
__array_wrap__ = interp2app(W_NDimArray.descr___array_wrap__),
__array_priority__ = GetSetProperty(W_NDimArray.descr___array_priority__),
__array__ = interp2app(W_NDimArray.descr___array__),
- __buffer__ = interp2app(W_NDimArray.buffer_w),
)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit