def test_gc(self):
        """refcount agnostic check that contained objects are freed"""
        def before_callback(parent):
            return r[0]

        def after_callback(parent):
            return r[1]

        class Obj(object):
            pass

        p = Obj()
        a = Obj()
        r = [Obj(), Obj()]
        weak_p = weakref.ref(p)
        weak_a = weakref.ref(a)
        weak_r0 = weakref.ref(r[0])
        weak_r1 = weakref.ref(r[1])
        weak_before = weakref.ref(before_callback)
        weak_after = weakref.ref(after_callback)
        kwds = dict(self.view_keywords)
        kwds['parent'] = p
        kwds['before'] = before_callback
        kwds['after'] = after_callback
        v = BufferProxy(kwds)
        v.some_attribute = a
        weak_v = weakref.ref(v)
        kwds = p = a = before_callback = after_callback = None
        gc.collect()
        self.assertTrue(weak_p() is not None)
        self.assertTrue(weak_a() is not None)
        self.assertTrue(weak_before() is not None)
        self.assertTrue(weak_after() is not None)
        v = None
        [gc.collect() for x in range(4)]
        self.assertTrue(weak_v() is None)
        self.assertTrue(weak_p() is None)
        self.assertTrue(weak_a() is None)
        self.assertTrue(weak_before() is None)
        self.assertTrue(weak_after() is None)
        self.assertTrue(weak_r0() is not None)
        self.assertTrue(weak_r1() is not None)
        r = None
        gc.collect()
        self.assertTrue(weak_r0() is None)
        self.assertTrue(weak_r1() is None)

        # Cycle removal
        kwds = dict(self.view_keywords)
        kwds['parent'] = []
        v = BufferProxy(kwds)
        v.some_attribute = v
        tracked = True
        for o in gc.get_objects():
            if o is v:
                break
        else:
            tracked = False
        self.assertTrue(tracked)
        kwds['parent'].append(v)
        kwds = None
        gc.collect()
        n1 = len(gc.garbage)
        v = None
        gc.collect()
        n2 = len(gc.garbage)
        self.assertEqual(n2, n1)
    def test_gc(self):
        """refcount agnostic check that contained objects are freed"""
        def before_callback(parent):
            return r[0]
        def after_callback(parent):
            return r[1]
        class Obj(object):
            pass
        p = Obj()
        a = Obj()
        r = [Obj(), Obj()]
        weak_p = weakref.ref(p)
        weak_a = weakref.ref(a)
        weak_r0 = weakref.ref(r[0])
        weak_r1 = weakref.ref(r[1])
        weak_before = weakref.ref(before_callback)
        weak_after = weakref.ref(after_callback)
        kwds = dict(self.view_keywords)
        kwds['parent'] = p
        kwds['before'] = before_callback
        kwds['after'] = after_callback
        v = BufferProxy(kwds)
        v.some_attribute = a
        weak_v = weakref.ref(v)
        kwds = p = a = before_callback = after_callback = None
        gc.collect()
        self.assertTrue(weak_p() is not None)
        self.assertTrue(weak_a() is not None)
        self.assertTrue(weak_before() is not None)
        self.assertTrue(weak_after() is not None)
        v = None
        gc.collect()
        self.assertTrue(weak_v() is None)
        self.assertTrue(weak_p() is None)
        self.assertTrue(weak_a() is None)
        self.assertTrue(weak_before() is None)
        self.assertTrue(weak_after() is None)
        self.assertTrue(weak_r0() is not None)
        self.assertTrue(weak_r1() is not None)
        r = None
        gc.collect()
        self.assertTrue(weak_r0() is None)
        self.assertTrue(weak_r1() is None)

        # Cycle removal
        kwds = dict(self.view_keywords)
        kwds['parent'] = []
        v = BufferProxy(kwds)
        v.some_attribute = v
        tracked = True
        for o in gc.get_objects():
            if o is v:
                break
        else:
            tracked = False
        self.assertTrue(tracked)
        kwds['parent'].append(v)
        kwds = None
        gc.collect()
        n1 = len(gc.garbage)
        v = None
        gc.collect()
        n2 = len(gc.garbage)
        self.assertEqual(n2, n1)