Author: Matti Picus <[email protected]>
Branch:
Changeset: r86973:f8f2080418c8
Date: 2016-09-09 13:59 +0300
http://bitbucket.org/pypy/pypy/changeset/f8f2080418c8/
Log: move all Py_buffer to memoryobject, create helper function
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,9 +1,7 @@
-from pypy.interpreter.error import oefmt
-from rpython.rtyper.lltypesystem import rffi, lltype
-from rpython.rlib.rarithmetic import widen
+from rpython.rtyper.lltypesystem import rffi
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, make_ref, incref
+ cpython_api, CANNOT_FAIL, Py_TPFLAGS_HAVE_NEWBUFFER)
+from pypy.module.cpyext.pyobject import PyObject
@cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)
def PyObject_CheckBuffer(space, pyobj):
@@ -14,102 +12,4 @@
return 1
return 0
-@cpython_api([PyObject, lltype.Ptr(Py_buffer), rffi.INT_real],
- rffi.INT_real, error=-1)
-def PyObject_GetBuffer(space, w_obj, view, flags):
- """Export obj into a Py_buffer, view. These arguments must
- never be NULL. The flags argument is a bit field indicating what
- kind of buffer the caller is prepared to deal with and therefore what
- kind of buffer the exporter is allowed to return. The buffer interface
- allows for complicated memory sharing possibilities, but some caller may
- not be able to handle all the complexity but may want to see if the
- exporter will let them take a simpler view to its memory.
-
- Some exporters may not be able to share memory in every possible way and
- may need to raise errors to signal to some consumers that something is
- just not possible. These errors should be a BufferError unless
- there is another error that is actually causing the problem. The
- exporter can use flags information to simplify how much of the
- Py_buffer structure is filled in with non-default values and/or
- raise an error if the object can't support a simpler view of its memory.
-
- 0 is returned on success and -1 on error."""
- flags = widen(flags)
- buf = space.buffer_w(w_obj, flags)
- try:
- view.c_buf = rffi.cast(rffi.VOIDP, buf.get_raw_address())
- except ValueError:
- raise BufferError("could not create buffer from object")
- view.c_len = buf.getlength()
- view.c_obj = make_ref(space, w_obj)
- ndim = buf.getndim()
- view.c_itemsize = buf.getitemsize()
- rffi.setintfield(view, 'c_readonly', int(buf.readonly))
- rffi.setintfield(view, 'c_ndim', ndim)
- view.c_format = rffi.str2charp(buf.getformat())
- view.c_shape = lltype.malloc(Py_ssize_tP.TO, ndim, flavor='raw')
- view.c_strides = lltype.malloc(Py_ssize_tP.TO, ndim, flavor='raw')
- shape = buf.getshape()
- strides = buf.getstrides()
- for i in range(ndim):
- view.c_shape[i] = shape[i]
- view.c_strides[i] = strides[i]
- view.c_suboffsets = lltype.nullptr(Py_ssize_tP.TO)
- view.c_internal = lltype.nullptr(rffi.VOIDP.TO)
- return 0
-
-def _IsFortranContiguous(view):
- ndim = widen(view.c_ndim)
- if ndim == 0:
- return 1
- 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.c_strides[i] != sd:
- return 0
- sd *= dim
- return 1
-
-def _IsCContiguous(view):
- ndim = widen(view.c_ndim)
- if ndim == 0:
- return 1
- 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.c_strides[i] != sd:
- return 0
- sd *= dim
- return 1
-
-
-@cpython_api([lltype.Ptr(Py_buffer), lltype.Char], rffi.INT_real,
error=CANNOT_FAIL)
-def PyBuffer_IsContiguous(space, view, fort):
- """Return 1 if the memory defined by the view is C-style (fortran is
- 'C') or Fortran-style (fortran is 'F') contiguous or either one
- (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.c_suboffsets:
- return 0
- if (fort == 'C'):
- return _IsCContiguous(view)
- elif (fort == 'F'):
- return _IsFortranContiguous(view)
- elif (fort == 'A'):
- return (_IsCContiguous(view) or _IsFortranContiguous(view))
- return 0
-
diff --git a/pypy/module/cpyext/memoryobject.py
b/pypy/module/cpyext/memoryobject.py
--- a/pypy/module/cpyext/memoryobject.py
+++ b/pypy/module/cpyext/memoryobject.py
@@ -2,10 +2,124 @@
Py_MAX_FMT, Py_MAX_NDIMS, build_type_checkers,
Py_ssize_tP)
from pypy.module.cpyext.pyobject import PyObject, make_ref, incref
from rpython.rtyper.lltypesystem import lltype, rffi
+from rpython.rlib.rarithmetic import widen
from pypy.objspace.std.memoryobject import W_MemoryView
PyMemoryView_Check, PyMemoryView_CheckExact =
build_type_checkers("MemoryView", "w_memoryview")
+@cpython_api([PyObject, lltype.Ptr(Py_buffer), rffi.INT_real],
+ rffi.INT_real, error=-1)
+def PyObject_GetBuffer(space, w_obj, view, flags):
+ """Export obj into a Py_buffer, view. These arguments must
+ never be NULL. The flags argument is a bit field indicating what
+ kind of buffer the caller is prepared to deal with and therefore what
+ kind of buffer the exporter is allowed to return. The buffer interface
+ allows for complicated memory sharing possibilities, but some caller may
+ not be able to handle all the complexity but may want to see if the
+ exporter will let them take a simpler view to its memory.
+
+ Some exporters may not be able to share memory in every possible way and
+ may need to raise errors to signal to some consumers that something is
+ just not possible. These errors should be a BufferError unless
+ there is another error that is actually causing the problem. The
+ exporter can use flags information to simplify how much of the
+ Py_buffer structure is filled in with non-default values and/or
+ raise an error if the object can't support a simpler view of its memory.
+
+ 0 is returned on success and -1 on error."""
+ flags = widen(flags)
+ buf = space.buffer_w(w_obj, flags)
+ try:
+ view.c_buf = rffi.cast(rffi.VOIDP, buf.get_raw_address())
+ except ValueError:
+ raise BufferError("could not create buffer from object")
+ return fill_Py_buffer(space, w_obj, view, flags)
+ view.c_obj = make_ref(space, w_obj)
+
+def fill_Py_buffer(space, buf, view):
+ # c_buf, c_obj have been filled in
+ ndim = buf.getndim()
+ view.c_len = buf.getlength()
+ view.c_itemsize = buf.getitemsize()
+ rffi.setintfield(view, 'c_ndim', ndim)
+ view.c_format = rffi.cast(rffi.CCHARP, view.c__format)
+ view.c_shape = rffi.cast(Py_ssize_tP, view.c__shape)
+ view.c_strides = rffi.cast(Py_ssize_tP, view.c__strides)
+ fmt = buf.getformat()
+ n = Py_MAX_FMT - 1 # NULL terminated buffer
+ if len(fmt) > n:
+ ### WARN?
+ pass
+ else:
+ n = len(fmt)
+ for i in range(n):
+ if ord(fmt[i]) > 255:
+ view.c_format[i] = '*'
+ else:
+ view.c_format[i] = fmt[i]
+ view.c_format[n] = '\x00'
+ shape = buf.getshape()
+ strides = buf.getstrides()
+ for i in range(ndim):
+ view.c_shape[i] = shape[i]
+ view.c_strides[i] = strides[i]
+ view.c_suboffsets = lltype.nullptr(Py_ssize_tP.TO)
+ view.c_internal = lltype.nullptr(rffi.VOIDP.TO)
+ return 0
+
+def _IsFortranContiguous(view):
+ ndim = widen(view.c_ndim)
+ if ndim == 0:
+ return 1
+ 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.c_strides[i] != sd:
+ return 0
+ sd *= dim
+ return 1
+
+def _IsCContiguous(view):
+ ndim = widen(view.c_ndim)
+ if ndim == 0:
+ return 1
+ 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.c_strides[i] != sd:
+ return 0
+ sd *= dim
+ return 1
+
+@cpython_api([lltype.Ptr(Py_buffer), lltype.Char], rffi.INT_real,
error=CANNOT_FAIL)
+def PyBuffer_IsContiguous(space, view, fort):
+ """Return 1 if the memory defined by the view is C-style (fortran is
+ 'C') or Fortran-style (fortran is 'F') contiguous or either one
+ (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.c_suboffsets:
+ return 0
+ if (fort == 'C'):
+ return _IsCContiguous(view)
+ elif (fort == 'F'):
+ return _IsFortranContiguous(view)
+ elif (fort == 'A'):
+ return (_IsCContiguous(view) or _IsFortranContiguous(view))
+ return 0
+
@cpython_api([PyObject], PyObject)
def PyMemoryView_FromObject(space, w_obj):
return space.call_method(space.builtin, "memoryview", w_obj)
@@ -38,31 +152,6 @@
view.c_obj = make_ref(space, w_s)
rffi.setintfield(view, 'c_readonly', 1)
isstr = True
- view.c_len = w_obj.getlength()
- view.c_itemsize = w_obj.buf.getitemsize()
- rffi.setintfield(view, 'c_ndim', ndim)
- view.c_format = rffi.cast(rffi.CCHARP, view.c__format)
- view.c_shape = rffi.cast(Py_ssize_tP, view.c__shape)
- view.c_strides = rffi.cast(Py_ssize_tP, view.c__strides)
- fmt = w_obj.buf.getformat()
- n = Py_MAX_FMT - 1 # NULL terminated buffer
- if len(fmt) > n:
- ### WARN?
- pass
- else:
- n = len(fmt)
- for i in range(n):
- if ord(fmt[i]) > 255:
- view.c_format[i] = '*'
- else:
- view.c_format[i] = fmt[i]
- view.c_format[n] = '\x00'
- shape = w_obj.buf.getshape()
- strides = w_obj.buf.getstrides()
- for i in range(ndim):
- view.c_shape[i] = shape[i]
- view.c_strides[i] = strides[i]
- view.c_suboffsets = lltype.nullptr(Py_ssize_tP.TO)
- view.c_internal = lltype.nullptr(rffi.VOIDP.TO)
+ fill_Py_buffer(space, w_obj.buf, view)
return view
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit