Author: Matti Picus <matti.pi...@gmail.com>
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
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to