]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Issue #14930: Make memoryview objects weakrefable.
authorRichard Oudkerk <shibturn@gmail.com>
Mon, 28 May 2012 20:35:09 +0000 (21:35 +0100)
committerRichard Oudkerk <shibturn@gmail.com>
Mon, 28 May 2012 20:35:09 +0000 (21:35 +0100)
Include/memoryobject.h
Lib/test/test_memoryview.py
Lib/test/test_sys.py
Misc/NEWS
Objects/memoryobject.c

index 4ac6f6525c91d1febde9b23b3c8d8fbadc4b5044..c2e11944467b657b979f410b4df426324f0cb04a 100644 (file)
@@ -63,6 +63,7 @@ typedef struct {
     Py_ssize_t exports;           /* number of buffer re-exports */
     Py_buffer view;               /* private copy of the exporter's view */
     char format[_Py_MEMORYVIEW_MAX_FORMAT]; /* used for casting */
+    PyObject *weakreflist;
     Py_ssize_t ob_array[1];       /* shape, strides, suboffsets */
 } PyMemoryViewObject;
 #endif
index 8809930acbeec14dcfd28a02fee1fd6f3c5f9cd4..5a33d035a187846d9ba14e629df95aa61c3844f7 100644 (file)
@@ -336,6 +336,21 @@ class AbstractMemoryTests:
         m = self._view(b)
         self.assertRaises(ValueError, hash, m)
 
+    def test_weakref(self):
+        # Check memoryviews are weakrefable
+        for tp in self._types:
+            b = tp(self._source)
+            m = self._view(b)
+            L = []
+            def callback(wr, b=b):
+                L.append(b)
+            wr = weakref.ref(m, callback)
+            self.assertIs(wr(), m)
+            del m
+            test.support.gc_collect()
+            self.assertIs(wr(), None)
+            self.assertIs(L[0], b)
+
 # Variations on source objects for the buffer: bytes-like objects, then arrays
 # with itemsize > 1.
 # NOTE: support for multi-dimensional objects is unimplemented.
index e3629ffc7cae5c9bc5ec66dd93350beac20f5ef9..b024d9a261c7102216802b57afe34e0645548b99 100644 (file)
@@ -778,7 +778,7 @@ class SizeofTest(unittest.TestCase):
         check(int(PyLong_BASE**2-1), size(vh) + 2*self.longdigit)
         check(int(PyLong_BASE**2), size(vh) + 3*self.longdigit)
         # memoryview
-        check(memoryview(b''), size(h + 'PPiP4P2i5P3cP'))
+        check(memoryview(b''), size(h + 'PPiP4P2i5P3c2P'))
         # module
         check(unittest, size(h + '3P'))
         # None
index 011cdf08fbf8742ea806d5c637e5948b831cde06..10f05d803b72d2de01b7c69fdf591d04b7f8ae8c 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,8 @@ What's New in Python 3.3.0 Alpha 4?
 Core and Builtins
 -----------------
 
+- Issue #14930: Make memoryview objects weakrefable.
+
 - Issue #14775: Fix a potential quadratic dict build-up due to the garbage
   collector repeatedly trying to untrack dicts.
 
index 67f7e01fe28c6f95befdc461aab3634c172455ed..62427d4b863f3498d03b2a92b93b5b36d393871d 100644 (file)
@@ -595,6 +595,7 @@ memory_alloc(int ndim)
     mv->view.shape = mv->ob_array;
     mv->view.strides = mv->ob_array + ndim;
     mv->view.suboffsets = mv->ob_array + 2 * ndim;
+    mv->weakreflist = NULL;
 
     _PyObject_GC_TRACK(mv);
     return mv;
@@ -969,6 +970,8 @@ memory_dealloc(PyMemoryViewObject *self)
     _PyObject_GC_UNTRACK(self);
     (void)_memory_release(self);
     Py_CLEAR(self->mbuf);
+    if (self->weakreflist != NULL)
+        PyObject_ClearWeakRefs((PyObject *) self);
     PyObject_GC_Del(self);
 }
 
@@ -2608,7 +2611,7 @@ PyTypeObject PyMemoryView_Type = {
     (traverseproc)memory_traverse,            /* tp_traverse */
     (inquiry)memory_clear,                    /* tp_clear */
     memory_richcompare,                       /* tp_richcompare */
-    0,                                        /* tp_weaklistoffset */
+    offsetof(PyMemoryViewObject, weakreflist),/* tp_weaklistoffset */
     0,                                        /* tp_iter */
     0,                                        /* tp_iternext */
     memory_methods,                           /* tp_methods */