[pypy-commit] pypy py3.5: Implement PyObject_GetBuffer in RPython

rlamy pypy.commits at gmail.com
Fri Dec 9 23:14:56 EST 2016


Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: py3.5
Changeset: r88990:3b7a9aafcab8
Date: 2016-12-10 03:06 +0000
http://bitbucket.org/pypy/pypy/changeset/3b7a9aafcab8/

Log:	Implement PyObject_GetBuffer in RPython

diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -519,7 +519,7 @@
     'PyObject_CallMethod', 'PyObject_CallFunctionObjArgs', 'PyObject_CallMethodObjArgs',
     '_PyObject_CallFunction_SizeT', '_PyObject_CallMethod_SizeT',
 
-    'PyObject_GetBuffer', 'PyBuffer_Release',
+    'PyBuffer_Release',
 
     'PyCObject_FromVoidPtr', 'PyCObject_FromVoidPtrAndDesc', 'PyCObject_AsVoidPtr',
     'PyCObject_GetDesc', 'PyCObject_Import', 'PyCObject_SetVoidPtr',
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
@@ -1,17 +1,40 @@
-from pypy.module.cpyext.api import (cpython_api, Py_buffer, CANNOT_FAIL,
-                         Py_MAX_FMT, Py_MAX_NDIMS, build_type_checkers, Py_ssize_tP)
-from pypy.module.cpyext.pyobject import PyObject, make_ref, incref, from_ref
 from rpython.rtyper.lltypesystem import lltype, rffi
 from rpython.rlib.rarithmetic import widen
+from pypy.interpreter.error import oefmt
 from pypy.objspace.std.memoryobject import W_MemoryView
+from pypy.module.cpyext.api import (
+    cpython_api, Py_buffer, CANNOT_FAIL, Py_MAX_FMT, Py_MAX_NDIMS,
+    build_type_checkers, Py_ssize_tP, generic_cpy_call)
+from pypy.module.cpyext.pyobject import PyObject, make_ref, from_ref
 from pypy.module.cpyext.import_ import PyImport_Import
+from pypy.module.cpyext.buffer import CBuffer
 
-from pypy.interpreter.error import oefmt
-from pypy.module.cpyext.pyobject import PyObject, from_ref
-from pypy.module.cpyext.buffer import CBuffer
-from pypy.objspace.std.memoryobject import W_MemoryView
 PyMemoryView_Check, PyMemoryView_CheckExact = build_type_checkers("MemoryView", "w_memoryview")
 
+
+ at cpython_api([PyObject, lltype.Ptr(Py_buffer), rffi.INT_real],
+             rffi.INT_real, error=-1)
+def PyObject_GetBuffer(space, exporter, view, flags):
+    """Send a request to exporter to fill in view as specified by flags. If the
+    exporter cannot provide a buffer of the exact type, it MUST raise
+    PyExc_BufferError, set view->obj to NULL and return -1.
+
+    On success, fill in view, set view->obj to a new reference to exporter and
+    return 0. In the case of chained buffer providers that redirect requests
+    to a single object, view->obj MAY refer to this object instead of exporter.
+
+    Successful calls to PyObject_GetBuffer() must be paired with calls to
+    PyBuffer_Release(), similar to malloc() and free(). Thus, after the
+    consumer is done with the buffer, PyBuffer_Release() must be called exactly
+    once.
+    """
+    pb = exporter.c_ob_type.c_tp_as_buffer
+    if not pb or not pb.c_bf_getbuffer:
+        w_exporter = from_ref(space, exporter)
+        raise oefmt(space.w_TypeError,
+            "a bytes-like object is required, not '%T'", w_exporter)
+    return generic_cpy_call(space, pb.c_bf_getbuffer, exporter, view, flags)
+
 def fill_Py_buffer(space, buf, view):
     # c_buf, c_obj have been filled in
     ndim = buf.getndim()
@@ -148,4 +171,3 @@
         rffi.setintfield(view, 'c_readonly', 1)
         isstr = True
     return view
-
diff --git a/pypy/module/cpyext/src/abstract.c b/pypy/module/cpyext/src/abstract.c
--- a/pypy/module/cpyext/src/abstract.c
+++ b/pypy/module/cpyext/src/abstract.c
@@ -98,20 +98,6 @@
 
 /* Buffer C-API for Python 3.0 */
 
-int
-PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags)
-{
-    PyBufferProcs *pb = obj->ob_type->tp_as_buffer;
-
-    if (pb == NULL || pb->bf_getbuffer == NULL) {
-        PyErr_Format(PyExc_TypeError,
-                     "a bytes-like object is required, not '%.100s'",
-                     Py_TYPE(obj)->tp_name);
-        return -1;
-    }
-    return (*pb->bf_getbuffer)(obj, view, flags);
-}
-
 void
 PyBuffer_Release(Py_buffer *view)
 {


More information about the pypy-commit mailing list