Test that in cases where the garbage cannot be collected, we raise an error, instead of hanging forever trying to clear it.
(self)
| 2105 | assert_no_gc_cycles(make_cycle) |
| 2106 | |
| 2107 | def test_fails(self): |
| 2108 | """ |
| 2109 | Test that in cases where the garbage cannot be collected, we raise an |
| 2110 | error, instead of hanging forever trying to clear it. |
| 2111 | """ |
| 2112 | |
| 2113 | class ReferenceCycleInDel: |
| 2114 | """ |
| 2115 | An object that not only contains a reference cycle, but creates new |
| 2116 | cycles whenever it's garbage-collected and its __del__ runs |
| 2117 | """ |
| 2118 | make_cycle = True |
| 2119 | |
| 2120 | def __init__(self): |
| 2121 | self.cycle = self |
| 2122 | |
| 2123 | def __del__(self): |
| 2124 | # break the current cycle so that `self` can be freed |
| 2125 | self.cycle = None |
| 2126 | |
| 2127 | if ReferenceCycleInDel.make_cycle: |
| 2128 | # but create a new one so that the garbage collector (GC) has more |
| 2129 | # work to do. |
| 2130 | ReferenceCycleInDel() |
| 2131 | |
| 2132 | try: |
| 2133 | w = weakref.ref(ReferenceCycleInDel()) |
| 2134 | try: |
| 2135 | with assert_raises(RuntimeError): |
| 2136 | # this will be unable to get a baseline empty garbage |
| 2137 | assert_no_gc_cycles(lambda: None) |
| 2138 | except AssertionError: |
| 2139 | # the above test is only necessary if the GC actually tried to free |
| 2140 | # our object anyway. |
| 2141 | if w() is not None: |
| 2142 | pytest.skip("GC does not call __del__ on cyclic objects") |
| 2143 | raise |
| 2144 | |
| 2145 | finally: |
| 2146 | # make sure that we stop creating reference cycles |
| 2147 | ReferenceCycleInDel.make_cycle = False |
nothing calls this directly
no test coverage detected