Skip to content

Commit 2efdeac

Browse files
committed
Update threading_helper.py from CPython v3.12.0a0
1 parent 1eb9ed1 commit 2efdeac

1 file changed

Lines changed: 43 additions & 10 deletions

File tree

Lib/test/support/threading_helper.py

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import sys
55
import threading
66
import time
7+
import unittest
78

89
from test import support
910

@@ -87,19 +88,17 @@ def wait_threads_exit(timeout=None):
8788
yield
8889
finally:
8990
start_time = time.monotonic()
90-
deadline = start_time + timeout
91-
while True:
91+
for _ in support.sleeping_retry(timeout, error=False):
92+
support.gc_collect()
9293
count = _thread._count()
9394
if count <= old_count:
9495
break
95-
if time.monotonic() > deadline:
96-
dt = time.monotonic() - start_time
97-
msg = (f"wait_threads() failed to cleanup {count - old_count} "
98-
f"threads after {dt:.1f} seconds "
99-
f"(count: {count}, old count: {old_count})")
100-
raise AssertionError(msg)
101-
time.sleep(0.010)
102-
support.gc_collect()
96+
else:
97+
dt = time.monotonic() - start_time
98+
msg = (f"wait_threads() failed to cleanup {count - old_count} "
99+
f"threads after {dt:.1f} seconds "
100+
f"(count: {count}, old count: {old_count})")
101+
raise AssertionError(msg)
103102

104103

105104
def join_thread(thread, timeout=None):
@@ -207,3 +206,37 @@ def __exit__(self, *exc_info):
207206
del self.exc_value
208207
del self.exc_traceback
209208
del self.thread
209+
210+
211+
def _can_start_thread() -> bool:
212+
"""Detect whether Python can start new threads.
213+
214+
Some WebAssembly platforms do not provide a working pthread
215+
implementation. Thread support is stubbed and any attempt
216+
to create a new thread fails.
217+
218+
- wasm32-wasi does not have threading.
219+
- wasm32-emscripten can be compiled with or without pthread
220+
support (-s USE_PTHREADS / __EMSCRIPTEN_PTHREADS__).
221+
"""
222+
if sys.platform == "emscripten":
223+
return sys._emscripten_info.pthreads
224+
elif sys.platform == "wasi":
225+
return False
226+
else:
227+
# assume all other platforms have working thread support.
228+
return True
229+
230+
can_start_thread = _can_start_thread()
231+
232+
def requires_working_threading(*, module=False):
233+
"""Skip tests or modules that require working threading.
234+
235+
Can be used as a function/class decorator or to skip an entire module.
236+
"""
237+
msg = "requires threading support"
238+
if module:
239+
if not can_start_thread:
240+
raise unittest.SkipTest(msg)
241+
else:
242+
return unittest.skipUnless(can_start_thread, msg)

0 commit comments

Comments
 (0)