Test for trac #796.
authorRobert Bradshaw <robertwb@gmail.com>
Wed, 2 Jan 2013 22:16:19 +0000 (14:16 -0800)
committerRobert Bradshaw <robertwb@gmail.com>
Wed, 2 Jan 2013 22:16:19 +0000 (14:16 -0800)
tests/run/double_dealloc_T796.pyx [new file with mode: 0644]

diff --git a/tests/run/double_dealloc_T796.pyx b/tests/run/double_dealloc_T796.pyx
new file mode 100644 (file)
index 0000000..c0904ae
--- /dev/null
@@ -0,0 +1,43 @@
+"""
+>>> x = SimpleGarbage()
+SimpleGarbage(1) __cinit__
+>>> del x
+SimpleGarbage(1) __dealloc__
+Collector.__dealloc__
+collect 0
+"""
+
+import gc, sys, weakref
+
+cdef int counter = 0
+cdef int next_counter():
+    global counter
+    counter += 1
+    return counter
+
+cdef class Collector:
+    # Indirectly trigger garbage collection in SimpleGarbage deallocation.
+    # The __dealloc__ method of SimpleGarbage won't trigger the bug as the
+    # refcount is artifitially inflated for the durration of that function.
+    def __dealloc__(self):
+        print "Collector.__dealloc__"
+        print "collect", gc.collect()
+
+cdef class SimpleGarbage:
+    cdef Collector c # to particpate in garbage collection
+    cdef int index
+    cdef bint deallocated
+    def __cinit__(self):
+        self.index = next_counter()
+        self.c = Collector()
+        print self, "__cinit__"
+    def __dealloc__(self):
+        print self, "__dealloc__"
+        if self.deallocated:
+            print "Double dealloc!"
+        self.deallocated = True
+        gc.collect()
+    def __str__(self):
+        return "SimpleGarbage(%s)" % self.index
+    def __repr__(self):
+        return "SimpleGarbage(%s)" % self.index