CPython has two test helpers that manage multithreading resource leaks:
-
test.support.threading_helper.threading_cleanup
documented asThreading support to prevent reporting refleaks when running regrtest.py -R
. Its implementation calls a garbage collector and printsthreading_cleanup() failed to cleanup xxx threads (count: yyy, dangling: zzz)
if leaks are detected -
test.libregtest.save_env.saved_test_environment
, also calls for GC and prints a report in case of detection. However, it also checks for leakage of many other resource types, not onlythreading._dangling
.
When some test leaks threads, we get a report from saved_test_environment
only:
Warning – threading._dangling was modified by test_deliberate_leakage
Warning – Before: {<weakref at 0x000002A431AA95D0; to ‘_MainThread’ at 0x000002A43163B710>}
Warning – After: {<weakref at 0x000002A431AAB1A0; to ‘Thread’ at 0x000002A431A93590>, <weakref at 0x000002A431AAAFC0; to ‘_MainThread’ at 0x000002A43163B710>}
test_deliberate_leakage ran no tests
A reproducer (Lib/test/test_deliberate_leakage.py
ran with python.bat -m test -v test_deliberate_leakage
):
from concurrent.futures import ThreadPoolExecutor
from test.support.threading_helper import threading_cleanup, threading_setup
from threading import Barrier
thread_info = threading_setup()
leaked_pool = ThreadPoolExecutor()
leaked_pool.submit(Barrier(2).wait)
threading_cleanup(*thread_info)
What is the reason behind such duplication? Do we need threading_setup
altogether?
For context, threading_setup was added in 2020, saved_test_environment was added in 2016.