| 26 | |
| 27 | |
| 28 | def threading_cleanup(*original_values): |
| 29 | orig_count, orig_ndangling = original_values |
| 30 | |
| 31 | timeout = 1.0 |
| 32 | for _ in support.sleeping_retry(timeout, error=False): |
| 33 | # Copy the thread list to get a consistent output. threading._dangling |
| 34 | # is a WeakSet, its value changes when it's read. |
| 35 | dangling_threads = list(threading._dangling) |
| 36 | count = _thread._count() |
| 37 | |
| 38 | if count <= orig_count: |
| 39 | return |
| 40 | |
| 41 | # Timeout! |
| 42 | support.environment_altered = True |
| 43 | support.print_warning( |
| 44 | f"threading_cleanup() failed to clean up threads " |
| 45 | f"in {timeout:.1f} seconds\n" |
| 46 | f" before: thread count={orig_count}, dangling={orig_ndangling}\n" |
| 47 | f" after: thread count={count}, dangling={len(dangling_threads)}") |
| 48 | for thread in dangling_threads: |
| 49 | support.print_warning(f"Dangling thread: {thread!r}") |
| 50 | |
| 51 | # The warning happens when a test spawns threads and some of these threads |
| 52 | # are still running after the test completes. To fix this warning, join |
| 53 | # threads explicitly to wait until they complete. |
| 54 | # |
| 55 | # To make the warning more likely, reduce the timeout. |
| 56 | |
| 57 | |
| 58 | def reap_threads(func): |