Keep a Python alive as long as possible. Create a reference cycle and store the cycle in an object deleted late in Python finalization. Try to keep the object alive until the very last garbage collection. The function keeps a strong reference by design. It should be called in
(obj)
| 2643 | |
| 2644 | |
| 2645 | def late_deletion(obj): |
| 2646 | """ |
| 2647 | Keep a Python alive as long as possible. |
| 2648 | |
| 2649 | Create a reference cycle and store the cycle in an object deleted late in |
| 2650 | Python finalization. Try to keep the object alive until the very last |
| 2651 | garbage collection. |
| 2652 | |
| 2653 | The function keeps a strong reference by design. It should be called in a |
| 2654 | subprocess to not mark a test as "leaking a reference". |
| 2655 | """ |
| 2656 | |
| 2657 | # Late CPython finalization: |
| 2658 | # - finalize_interp_clear() |
| 2659 | # - _PyInterpreterState_Clear(): Clear PyInterpreterState members |
| 2660 | # (ex: codec_search_path, before_forkers) |
| 2661 | # - clear os.register_at_fork() callbacks |
| 2662 | # - clear codecs.register() callbacks |
| 2663 | |
| 2664 | ref_cycle = [obj] |
| 2665 | ref_cycle.append(ref_cycle) |
| 2666 | |
| 2667 | # Store a reference in PyInterpreterState.codec_search_path |
| 2668 | import codecs |
| 2669 | def search_func(encoding): |
| 2670 | return None |
| 2671 | search_func.reference = ref_cycle |
| 2672 | codecs.register(search_func) |
| 2673 | |
| 2674 | if hasattr(os, 'register_at_fork'): |
| 2675 | # Store a reference in PyInterpreterState.before_forkers |
| 2676 | def atfork_func(): |
| 2677 | pass |
| 2678 | atfork_func.reference = ref_cycle |
| 2679 | os.register_at_fork(before=atfork_func) |
| 2680 | |
| 2681 | |
| 2682 | def busy_retry(timeout, err_msg=None, /, *, error=True): |
no test coverage detected
searching dependent graphs…