MCPcopy Index your code
hub / github.com/python/cpython / test_function_tp_clear_leaves_consistent_state

Method test_function_tp_clear_leaves_consistent_state

Lib/test/test_gc.py:239–310  ·  view source on GitHub ↗
(self)

Source from the content-addressed store, hash-verified

237 self.assertIn(gc.collect(), (2, 3))
238
239 def test_function_tp_clear_leaves_consistent_state(self):
240 # https://github.com/python/cpython/issues/91636
241 code = """if 1:
242
243 import gc
244 import weakref
245
246 class LateFin:
247 __slots__ = ('ref',)
248
249 def __del__(self):
250
251 # 8. Now `latefin`'s finalizer is called. Here we
252 # obtain a reference to `func`, which is currently
253 # undergoing `tp_clear`.
254 global func
255 func = self.ref()
256
257 class Cyclic(tuple):
258 __slots__ = ()
259
260 # 4. The finalizers of all garbage objects are called. In
261 # this case this is only us as `func` doesn't have a
262 # finalizer.
263 def __del__(self):
264
265 # 5. Create a weakref to `func` now. In previous
266 # versions of Python, this would avoid having it
267 # cleared by the garbage collector before calling
268 # the finalizers. Now, weakrefs get cleared after
269 # calling finalizers.
270 self[1].ref = weakref.ref(self[0])
271
272 # 6. Drop the global reference to `latefin`. The only
273 # remaining reference is the one we have.
274 global latefin
275 del latefin
276
277 # 7. Now `func` is `tp_clear`-ed. This drops the last
278 # reference to `Cyclic`, which gets `tp_dealloc`-ed.
279 # This drops the last reference to `latefin`.
280
281 latefin = LateFin()
282 def func():
283 pass
284 cyc = tuple.__new__(Cyclic, (func, latefin))
285
286 # 1. Create a reference cycle of `cyc` and `func`.
287 func.__module__ = cyc
288
289 # 2. Make the cycle unreachable, but keep the global reference
290 # to `latefin` so that it isn't detected as garbage. This
291 # way its finalizer will not be called immediately.
292 del func, cyc
293
294 # 3. Invoke garbage collection,
295 # which will find `cyc` and `func` as garbage.
296 gc.collect()

Callers

nothing calls this directly

Calls 4

assert_python_okFunction · 0.90
assertRegexMethod · 0.80
assertFalseMethod · 0.80
assertEqualMethod · 0.45

Tested by

no test coverage detected