[pypy-commit] pypy default: test, fix buffer_attach with a CBuffer. Alos add comment that except segfaults

mattip pypy.commits at gmail.com
Wed Jun 26 07:16:17 EDT 2019


Author: Matti Picus <matti.picus at gmail.com>
Branch: 
Changeset: r96866:cc5fc1bad809
Date: 2019-06-26 14:15 +0300
http://bitbucket.org/pypy/pypy/changeset/cc5fc1bad809/

Log:	test, fix buffer_attach with a CBuffer. Alos add comment that except
	segfaults

diff --git a/pypy/module/cpyext/bufferobject.py b/pypy/module/cpyext/bufferobject.py
--- a/pypy/module/cpyext/bufferobject.py
+++ b/pypy/module/cpyext/bufferobject.py
@@ -5,6 +5,7 @@
     cpython_api, Py_ssize_t, cpython_struct, bootstrap_function, slot_function,
     PyObjectFields, PyObject)
 from pypy.module.cpyext.pyobject import make_typedescr, decref, make_ref
+from pypy.module.cpyext.buffer import CBuffer
 from pypy.module.array.interp_array import ArrayBuffer
 from pypy.objspace.std.bufferobject import W_Buffer
 
@@ -33,7 +34,7 @@
 
 def buffer_attach(space, py_obj, w_obj, w_userdata=None):
     """
-    Fills a newly allocated PyBufferObject with the given (str) buffer object.
+    Fills a newly allocated PyBufferObject with the given buffer object.
     """
     py_buf = rffi.cast(PyBufferObject, py_obj)
     py_buf.c_b_offset = 0
@@ -60,7 +61,17 @@
         py_buf.c_b_base = make_ref(space, w_base)
         py_buf.c_b_ptr = rffi.cast(rffi.VOIDP, buf.w_array._charbuf_start())
         py_buf.c_b_size = buf.getlength()
+    elif isinstance(buf, CBuffer):
+        py_buf.c_b_base = make_ref(space, buf.view.w_obj)
+        py_buf.c_b_ptr = rffi.cast(rffi.VOIDP, buf.view.ptr)
+        py_buf.c_b_size = buf.getlength()
     else:
+        # Raising in attach will segfault.
+        # It would be nice if we could handle the error more gracefully
+        # with something like this
+        # py_buf.c_b_base = lltype.nullptr(PyObject.TO)
+        # py_buf.c_b_ptr = rffi.cast(rffi.VOIDP, 0)
+        # py_buf.c_b_size = buf.getlength()
         raise oefmt(space.w_NotImplementedError, "buffer flavor not supported")
 
 
diff --git a/pypy/module/cpyext/test/array.c b/pypy/module/cpyext/test/array.c
--- a/pypy/module/cpyext/test/array.c
+++ b/pypy/module/cpyext/test/array.c
@@ -2573,6 +2573,11 @@
     Py_RETURN_NONE;
 }
 
+static PyObject *
+passthrough(PyObject *self, PyObject* args) {
+    Py_INCREF(args);
+    return args;
+} 
 /*********************** Install Module **************************/
 
 static PyMethodDef a_methods[] = {
@@ -2584,6 +2589,7 @@
     {"same_dealloc",   (PyCFunction)same_dealloc, METH_VARARGS, NULL},
     {"getitem", (PyCFunction)getitem, METH_VARARGS, NULL},
     {"subclass_with_attribute", (PyCFunction)subclass_with_attribute, METH_VARARGS, NULL},
+    {"passthrough", (PyCFunction)passthrough, METH_O, NULL},
     {NULL, NULL, 0, NULL}        /* Sentinel */
 };
 
diff --git a/pypy/module/cpyext/test/test_arraymodule.py b/pypy/module/cpyext/test/test_arraymodule.py
--- a/pypy/module/cpyext/test/test_arraymodule.py
+++ b/pypy/module/cpyext/test/test_arraymodule.py
@@ -79,6 +79,9 @@
         assert str(buffer('a') + arr) == "a" + expected
         # python2 special cases empty-buffer + obj
         assert str(buffer('') + arr) == "array('i', [1, 2, 3, 4])"
+        # make sure buffer_attach is called
+        buf2 = module.passthrough(buf)
+        assert str(buf2) == str(buf)
 
     def test_releasebuffer(self):
         module = self.import_module(name='array')


More information about the pypy-commit mailing list