diff -r b8a665a36f7b Lib/test/test_memoryview.py --- a/Lib/test/test_memoryview.py Thu Aug 21 05:02:47 2008 +0200 +++ b/Lib/test/test_memoryview.py Thu Aug 28 13:21:04 2008 +0200 @@ -157,6 +157,18 @@ m = self.check_attributes_with_type(bytearray) self.assertEquals(m.readonly, False) + def test_getbuffer(self): + # Test PyObject_GetBuffer() on a memoryview object. + b = self.base_object + oldrefcount = sys.getrefcount(b) + m = self._view(b) + oldviewrefcount = sys.getrefcount(m) + s = str(m, "utf-8") + self._check_contents(b, s.encode("utf-8")) + self.assertEquals(sys.getrefcount(m), oldviewrefcount) + m = None + self.assertEquals(sys.getrefcount(b), oldrefcount) + class MemoryviewTest(unittest.TestCase, CommonMemoryTests): diff -r b8a665a36f7b Objects/memoryobject.c --- a/Objects/memoryobject.c Thu Aug 21 05:02:47 2008 +0200 +++ b/Objects/memoryobject.c Thu Aug 28 13:21:04 2008 +0200 @@ -3,24 +3,34 @@ #include "Python.h" +static void +dup_buffer(Py_buffer *dest, Py_buffer *src) +{ + *dest = *src; + if (src->shape == &(src->len)) + dest->shape = &(dest->len); + if (src->strides == &(src->itemsize)) + dest->strides = &(dest->itemsize); +} + static int memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags) { - if (view != NULL) { - if (self->view.obj) - Py_INCREF(self->view.obj); - *view = self->view; - } - if (self->view.obj == NULL) - return 0; - return self->view.obj->ob_type->tp_as_buffer->bf_getbuffer( - self->view.obj, NULL, PyBUF_FULL); + int res = 0; + /* XXX for whatever reason fixing the flags seems necessary */ + if (self->view.readonly) + flags &= ~PyBUF_WRITABLE; + if (self->view.obj != NULL) + res = PyObject_GetBuffer(self->view.obj, view, flags); + if (view) + dup_buffer(view, &self->view); + return res; } static void memory_releasebuf(PyMemoryViewObject *self, Py_buffer *view) { - PyBuffer_Release(&self->view); + PyBuffer_Release(view); } PyDoc_STRVAR(memory_doc, @@ -37,12 +47,7 @@ &PyMemoryView_Type); if (mview == NULL) return NULL; mview->base = NULL; - /* XXX there should be an API to duplicate a buffer object */ - mview->view = *info; - if (info->shape == &(info->len)) - mview->view.shape = &(mview->view.len); - if (info->strides == &(info->itemsize)) - mview->view.strides = &(mview->view.itemsize); + dup_buffer(&mview->view, info); /* NOTE: mview->view.obj should already have been incref'ed as part of PyBuffer_FillInfo(). */ return (PyObject *)mview;