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