Author: Ronan Lamy <ronan.l...@gmail.com>
Branch: buffer-cleanup
Changeset: r89988:6f7a4aa078bd
Date: 2017-02-07 03:08 +0000
http://bitbucket.org/pypy/pypy/changeset/6f7a4aa078bd/

Log:    Test and fix for the fields of the Py_buffer not being set correctly
        in our bf_getbuffer

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,10 +1,10 @@
 from rpython.rtyper.lltypesystem import rffi, lltype
 from pypy.interpreter.error import oefmt
 from pypy.module.cpyext.api import (
-    cpython_api, Py_buffer, Py_ssize_t, Py_ssize_tP, CONST_STRINGP,
+    cpython_api, Py_buffer, Py_ssize_t, Py_ssize_tP, CONST_STRINGP, cts,
     generic_cpy_call,
     PyBUF_WRITABLE, PyBUF_FORMAT, PyBUF_ND, PyBUF_STRIDES, PyBUF_SIMPLE)
-from pypy.module.cpyext.pyobject import PyObject, Py_IncRef, Py_DecRef
+from pypy.module.cpyext.pyobject import PyObject, incref, Py_DecRef
 
 @cpython_api([PyObject, CONST_STRINGP, Py_ssize_tP], rffi.INT_real, error=-1)
 def PyObject_AsCharBuffer(space, obj, bufferp, sizep):
@@ -35,6 +35,33 @@
         Py_DecRef(space, view.c_obj)
     return 0
 
+def fill_buffer(space, view, pybuf, py_obj):
+    view.c_buf = cts.cast('void *', pybuf.get_raw_address())
+    view.c_obj = py_obj
+    if py_obj:
+        incref(space, py_obj)
+    view.c_len = pybuf.getlength()
+    view.c_itemsize = pybuf.getitemsize()
+    rffi.setintfield(view, 'c_readonly', int(pybuf.readonly))
+    rffi.setintfield(view, 'c_ndim', pybuf.getndim())
+    view.c_format = rffi.str2charp(pybuf.getformat())
+    shape = pybuf.getshape()
+    if not shape:
+        view.c_shape = lltype.nullptr(Py_ssize_tP.TO)
+    else:
+        view.c_shape = cts.cast('Py_ssize_t*', view.c__shape)
+        for i, n in enumerate(shape):
+            view.c_shape[i] = n
+    strides = pybuf.getstrides()
+    if not strides:
+        view.c_strides = lltype.nullptr(Py_ssize_tP.TO)
+    else:
+        view.c_strides = cts.cast('Py_ssize_t*', view.c__strides)
+        for i, n in enumerate(strides):
+            view.c_strides[i] = n
+    view.c_suboffsets = lltype.nullptr(Py_ssize_tP.TO)
+    view.c_internal = lltype.nullptr(rffi.VOIDP.TO)
+
 
 @cpython_api([lltype.Ptr(Py_buffer), PyObject, rffi.VOIDP, Py_ssize_t,
               lltype.Signed, lltype.Signed], rffi.INT, error=-1)
@@ -51,7 +78,7 @@
     view.c_len = length
     view.c_obj = obj
     if obj:
-        Py_IncRef(space, obj)
+        incref(space, obj)
     view.c_itemsize = 1
     rffi.setintfield(view, 'c_readonly', readonly)
     rffi.setintfield(view, 'c_ndim', 1)
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
@@ -2871,7 +2871,17 @@
     return PyBytes_FromStringAndSize((char*)ptr, size);
 }
 
-
+static PyObject *
+write_buffer_len(PyObject * self, PyObject * obj)
+{
+    void* buf;
+    Py_ssize_t buf_len;
+    if (PyObject_AsWriteBuffer(obj, &buf, &buf_len) < 0) {
+        PyErr_SetString(PyExc_ValueError, "bad value");
+        return NULL;
+    }
+    return PyLong_FromLong(buf_len);
+}
 
 /*********************** Install Module **************************/
 
@@ -2880,6 +2890,7 @@
      PyDoc_STR("Internal. Used for pickling support.")},
     {"switch_multiply",   (PyCFunction)switch_multiply, METH_NOARGS, NULL},
     {"readbuffer_as_string",   (PyCFunction)readbuffer_as_string, 
METH_VARARGS, NULL},
+    {"write_buffer_len", write_buffer_len, 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
@@ -84,6 +84,9 @@
         arr = module.array('u', '123')
         view = memoryview(arr)
         assert view.itemsize == 4
+        assert module.write_buffer_len(arr) == 12
+        assert len(module.readbuffer_as_string(arr)) == 12
+        assert len(module.readbuffer_as_string(view)) == 12
 
     def test_subclass(self):
         import struct
diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py
--- a/pypy/module/cpyext/typeobject.py
+++ b/pypy/module/cpyext/typeobject.py
@@ -555,11 +555,10 @@
 
 @slot_function([PyObject, lltype.Ptr(Py_buffer), rffi.INT_real], 
rffi.INT_real, error=-1)
 def bf_getbuffer(space, w_obj, view, flags):
-    from pypy.module.cpyext.buffer import PyBuffer_FillInfo
+    from pypy.module.cpyext.buffer import fill_buffer
     buf = space.buffer_w(w_obj, rffi.cast(lltype.Signed, flags))
-    c_buf = rffi.cast(rffi.VOIDP, buf.get_raw_address())
-    return PyBuffer_FillInfo(space, view, w_obj, c_buf,
-                             space.len_w(w_obj), 0, flags)
+    fill_buffer(space, view, buf, as_pyobj(space, w_obj))
+    return 0
 
 def setup_buffer_procs(space, w_type, pto):
     bufspec = w_type.layout.typedef.buffer
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to