Author: Ronan Lamy <ronan.l...@gmail.com>
Branch: fix-cpyext-releasebuffer
Changeset: r90472:99ed56433685
Date: 2017-03-02 11:07 +0100
http://bitbucket.org/pypy/pypy/changeset/99ed56433685/

Log:    Add new buffer to array.c and test that bf_releasebuffer is called
        (failing)

diff --git a/pypy/module/cpyext/slotdefs.py b/pypy/module/cpyext/slotdefs.py
--- a/pypy/module/cpyext/slotdefs.py
+++ b/pypy/module/cpyext/slotdefs.py
@@ -468,11 +468,12 @@
         ptr = pybuf.c_buf
         size = pybuf.c_len
         ndim = widen(pybuf.c_ndim)
-        shape =   [pybuf.c_shape[i]   for i in range(ndim)]
+        shape = None
+        if pybuf.c_shape:
+            shape = [pybuf.c_shape[i]   for i in range(ndim)]
+        strides = None
         if pybuf.c_strides:
             strides = [pybuf.c_strides[i] for i in range(ndim)]
-        else:
-            strides = [1]
         if pybuf.c_format:
             format = rffi.charp2str(pybuf.c_format)
         else:
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
@@ -1893,10 +1893,10 @@
     }
     else if(obj1->ob_type == &Arraytype)
         fprintf(stderr, "\nCannot multiply array of type %c and %s\n",
-            ((arrayobject*)obj1)->ob_descr->typecode, obj2->ob_type->tp_name); 
+            ((arrayobject*)obj1)->ob_descr->typecode, obj2->ob_type->tp_name);
     else if(obj2->ob_type == &Arraytype)
         fprintf(stderr, "\nCannot multiply array of type %c and %s\n",
-            ((arrayobject*)obj2)->ob_descr->typecode, obj1->ob_type->tp_name); 
+            ((arrayobject*)obj2)->ob_descr->typecode, obj1->ob_type->tp_name);
     Py_INCREF(Py_NotImplemented);
     return Py_NotImplemented;
 }
@@ -1947,10 +1947,10 @@
     }
     else if(obj1->ob_type == &Arraytype)
         fprintf(stderr, "\nCannot multiply array of type %c and %s\n",
-            ((arrayobject*)obj1)->ob_descr->typecode, obj2->ob_type->tp_name); 
+            ((arrayobject*)obj1)->ob_descr->typecode, obj2->ob_type->tp_name);
     else if(obj2->ob_type == &Arraytype)
         fprintf(stderr, "\nCannot multiply array of type %c and %s\n",
-            ((arrayobject*)obj2)->ob_descr->typecode, obj1->ob_type->tp_name); 
+            ((arrayobject*)obj2)->ob_descr->typecode, obj1->ob_type->tp_name);
     Py_INCREF(Py_NotImplemented);
     return Py_NotImplemented;
 }
@@ -2006,6 +2006,29 @@
     return 1;
 }
 
+static int
+array_getbuffer(PyObject* obj, Py_buffer* view, int flags)
+{
+    arrayobject* self = (arrayobject*)obj;
+    return PyBuffer_FillInfo(view, obj, self->ob_item,
+            Py_SIZE(self)*self->ob_descr->itemsize, 0, flags);
+}
+
+static long releasebuffer_cnt = 0;
+
+static PyObject *
+get_releasebuffer_cnt(void)
+{
+    return PyLong_FromLong(releasebuffer_cnt);
+}
+
+static void
+array_releasebuffer(arrayobject* self)
+{
+    releasebuffer_cnt++;
+    return;
+}
+
 static PySequenceMethods array_as_sequence = {
     (lenfunc)array_length,                      /*sq_length*/
     (binaryfunc)array_concat,               /*sq_concat*/
@@ -2024,6 +2047,8 @@
     (writebufferproc)array_buffer_getwritebuf,
     (segcountproc)array_buffer_getsegcount,
     NULL,
+    (getbufferproc)array_getbuffer,
+    (releasebufferproc)array_releasebuffer
 };
 
 static PyObject *
@@ -2237,7 +2262,7 @@
     PyObject_GenericGetAttr,                    /* tp_getattro */
     0,                                          /* tp_setattro */
     &array_as_buffer,                           /* tp_as_buffer*/
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | 
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
     Py_TPFLAGS_HAVE_WEAKREFS | Py_TPFLAGS_CHECKTYPES,  /* tp_flags */
     arraytype_doc,                              /* tp_doc */
     0,                                          /* tp_traverse */
@@ -2280,8 +2305,9 @@
     PyObject_GenericGetAttr,                    /* tp_getattro */
     0,                                          /* tp_setattro */
     &array_as_buffer,                           /* tp_as_buffer*/
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | 
-    Py_TPFLAGS_HAVE_WEAKREFS | Py_TPFLAGS_CHECKTYPES,  /* tp_flags */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
+    Py_TPFLAGS_HAVE_WEAKREFS | Py_TPFLAGS_CHECKTYPES |
+    Py_TPFLAGS_HAVE_NEWBUFFER,                  /* tp_flags */
     arraytype_doc,                              /* tp_doc */
     0,                                          /* tp_traverse */
     0,                                          /* tp_clear */
@@ -2409,6 +2435,16 @@
     return PyString_FromStringAndSize((char*)ptr, size);
 }
 
+static PyObject *
+create_and_release_buffer(PyObject *self, PyObject *obj)
+{
+    Py_buffer view;
+    int res = PyObject_GetBuffer(obj, &view, 0);
+    if (res < 0)
+        return NULL;
+    PyBuffer_Release(&view);
+    Py_RETURN_NONE;
+}
 
 
 /*********************** Install Module **************************/
@@ -2417,6 +2453,8 @@
     {"_reconstruct",   (PyCFunction)_reconstruct, METH_VARARGS, NULL},
     {"switch_multiply",   (PyCFunction)switch_multiply, METH_NOARGS, NULL},
     {"readbuffer_as_string",   (PyCFunction)readbuffer_as_string, 
METH_VARARGS, NULL},
+    {"get_releasebuffer_cnt",   (PyCFunction)get_releasebuffer_cnt, 
METH_NOARGS, NULL},
+    {"create_and_release_buffer",   (PyCFunction)create_and_release_buffer, 
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
@@ -78,6 +78,23 @@
                                 '\x03\0\0\0'
                                 '\x04\0\0\0')
 
+    def test_releasebuffer(self):
+        module = self.import_module(name='array')
+        arr = module.array('i', [1,2,3,4])
+        assert module.get_releasebuffer_cnt() == 0
+        module.create_and_release_buffer(arr)
+        assert module.get_releasebuffer_cnt() == 1
+
+    def test_Py_buffer(self):
+        module = self.import_module(name='array')
+        arr = module.array('i', [1,2,3,4])
+        assert module.get_releasebuffer_cnt() == 0
+        m = memoryview(arr)
+        assert module.get_releasebuffer_cnt() == 0
+        del m
+        self.debug_collect()
+        assert module.get_releasebuffer_cnt() == 1
+
     def test_pickle(self):
         import pickle
         module = self.import_module(name='array')
@@ -107,7 +124,7 @@
         arr = Sub('i', [2])
         res = [1, 2, 3] * arr
         assert res == [1, 2, 3, 1, 2, 3]
-        
+
         val = module.readbuffer_as_string(arr)
         assert val == struct.pack('i', 2)
 
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to