Skip to content

Commit e80697d

Browse files
authored
bpo-40275: Adding threading_helper submodule in test.support (GH-20263)
1 parent 7d80b35 commit e80697d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+483
-428
lines changed

Doc/library/test.rst

Lines changed: 78 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -838,18 +838,6 @@ The :mod:`test.support` module defines the following functions:
838838
.. versionadded:: 3.9
839839

840840

841-
.. function:: wait_threads_exit(timeout=60.0)
842-
843-
Context manager to wait until all threads created in the ``with`` statement
844-
exit.
845-
846-
847-
.. function:: start_threads(threads, unlock=None)
848-
849-
Context manager to start *threads*. It attempts to join the threads upon
850-
exit.
851-
852-
853841
.. function:: calcobjsize(fmt)
854842

855843
Return :func:`struct.calcsize` for ``nP{fmt}0n`` or, if ``gettotalrefcount``
@@ -988,11 +976,6 @@ The :mod:`test.support` module defines the following functions:
988976
the trace function.
989977

990978

991-
.. decorator:: reap_threads(func)
992-
993-
Decorator to ensure the threads are cleaned up even if the test fails.
994-
995-
996979
.. decorator:: bigmemtest(size, memuse, dry_run=True)
997980

998981
Decorator for bigmem tests.
@@ -1110,23 +1093,6 @@ The :mod:`test.support` module defines the following functions:
11101093
preserve internal cache.
11111094

11121095

1113-
.. function:: threading_setup()
1114-
1115-
Return current thread count and copy of dangling threads.
1116-
1117-
1118-
.. function:: threading_cleanup(*original_values)
1119-
1120-
Cleanup up threads not specified in *original_values*. Designed to emit
1121-
a warning if a test leaves running threads in the background.
1122-
1123-
1124-
.. function:: join_thread(thread, timeout=30.0)
1125-
1126-
Join a *thread* within *timeout*. Raise an :exc:`AssertionError` if thread
1127-
is still alive after *timeout* seconds.
1128-
1129-
11301096
.. function:: reap_children()
11311097

11321098
Use this at the end of ``test_main`` whenever sub-processes are started.
@@ -1140,39 +1106,6 @@ The :mod:`test.support` module defines the following functions:
11401106
is raised.
11411107

11421108

1143-
.. function:: catch_threading_exception()
1144-
1145-
Context manager catching :class:`threading.Thread` exception using
1146-
:func:`threading.excepthook`.
1147-
1148-
Attributes set when an exception is catched:
1149-
1150-
* ``exc_type``
1151-
* ``exc_value``
1152-
* ``exc_traceback``
1153-
* ``thread``
1154-
1155-
See :func:`threading.excepthook` documentation.
1156-
1157-
These attributes are deleted at the context manager exit.
1158-
1159-
Usage::
1160-
1161-
with support.catch_threading_exception() as cm:
1162-
# code spawning a thread which raises an exception
1163-
...
1164-
1165-
# check the thread exception, use cm attributes:
1166-
# exc_type, exc_value, exc_traceback, thread
1167-
...
1168-
1169-
# exc_type, exc_value, exc_traceback, thread attributes of cm no longer
1170-
# exists at this point
1171-
# (to avoid reference cycles)
1172-
1173-
.. versionadded:: 3.8
1174-
1175-
11761109
.. function:: catch_unraisable_exception()
11771110

11781111
Context manager catching unraisable exception using
@@ -1628,3 +1561,81 @@ The module defines the following class:
16281561
.. method:: BytecodeTestCase.assertNotInBytecode(x, opname, argval=_UNSPECIFIED)
16291562

16301563
Throws :exc:`AssertionError` if *opname* is found.
1564+
1565+
1566+
:mod:`test.support.threading_helper` --- Utilities for threading tests
1567+
======================================================================
1568+
1569+
.. module:: test.support.threading_helper
1570+
:synopsis: Support for threading tests.
1571+
1572+
The :mod:`test.support.threading_helper` module provides support for threading tests.
1573+
1574+
.. versionadded:: 3.10
1575+
1576+
1577+
.. function:: join_thread(thread, timeout=None)
1578+
1579+
Join a *thread* within *timeout*. Raise an :exc:`AssertionError` if thread
1580+
is still alive after *timeout* seconds.
1581+
1582+
1583+
.. decorator:: reap_threads(func)
1584+
1585+
Decorator to ensure the threads are cleaned up even if the test fails.
1586+
1587+
1588+
.. function:: start_threads(threads, unlock=None)
1589+
1590+
Context manager to start *threads*. It attempts to join the threads upon
1591+
exit.
1592+
1593+
1594+
.. function:: threading_cleanup(*original_values)
1595+
1596+
Cleanup up threads not specified in *original_values*. Designed to emit
1597+
a warning if a test leaves running threads in the background.
1598+
1599+
1600+
.. function:: threading_setup()
1601+
1602+
Return current thread count and copy of dangling threads.
1603+
1604+
1605+
.. function:: wait_threads_exit(timeout=None)
1606+
1607+
Context manager to wait until all threads created in the ``with`` statement
1608+
exit.
1609+
1610+
1611+
.. function:: catch_threading_exception()
1612+
1613+
Context manager catching :class:`threading.Thread` exception using
1614+
:func:`threading.excepthook`.
1615+
1616+
Attributes set when an exception is catched:
1617+
1618+
* ``exc_type``
1619+
* ``exc_value``
1620+
* ``exc_traceback``
1621+
* ``thread``
1622+
1623+
See :func:`threading.excepthook` documentation.
1624+
1625+
These attributes are deleted at the context manager exit.
1626+
1627+
Usage::
1628+
1629+
with threading_helper.catch_threading_exception() as cm:
1630+
# code spawning a thread which raises an exception
1631+
...
1632+
1633+
# check the thread exception, use cm attributes:
1634+
# exc_type, exc_value, exc_traceback, thread
1635+
...
1636+
1637+
# exc_type, exc_value, exc_traceback, thread attributes of cm no longer
1638+
# exists at this point
1639+
# (to avoid reference cycles)
1640+
1641+
.. versionadded:: 3.8

Lib/test/_test_multiprocessing.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import test.support.script_helper
2828
from test import support
2929
from test.support import socket_helper
30+
from test.support import threading_helper
3031

3132

3233
# Skip tests if _multiprocessing wasn't built.
@@ -81,7 +82,7 @@ def close_queue(queue):
8182
def join_process(process):
8283
# Since multiprocessing.Process has the same API than threading.Thread
8384
# (join() and is_alive(), the support function can be reused
84-
support.join_thread(process)
85+
threading_helper.join_thread(process)
8586

8687

8788
if os.name == "posix":
@@ -4234,7 +4235,7 @@ def make_finalizers():
42344235
gc.set_threshold(5, 5, 5)
42354236
threads = [threading.Thread(target=run_finalizers),
42364237
threading.Thread(target=make_finalizers)]
4237-
with test.support.start_threads(threads):
4238+
with threading_helper.start_threads(threads):
42384239
time.sleep(4.0) # Wait a bit to trigger race condition
42394240
finish = True
42404241
if exc is not None:

Lib/test/fork_wait.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import os, sys, time, unittest
1313
import threading
1414
from test import support
15+
from test.support import threading_helper
1516

1617

1718
LONGSLEEP = 2
@@ -21,7 +22,7 @@
2122
class ForkWait(unittest.TestCase):
2223

2324
def setUp(self):
24-
self._threading_key = support.threading_setup()
25+
self._threading_key = threading_helper.threading_setup()
2526
self.alive = {}
2627
self.stop = 0
2728
self.threads = []
@@ -33,7 +34,7 @@ def tearDown(self):
3334
thread.join()
3435
thread = None
3536
self.threads.clear()
36-
support.threading_cleanup(*self._threading_key)
37+
threading_helper.threading_cleanup(*self._threading_key)
3738

3839
def f(self, id):
3940
while not self.stop:

Lib/test/lock_tests.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import weakref
1212

1313
from test import support
14+
from test.support import threading_helper
1415

1516

1617
requires_fork = unittest.skipUnless(hasattr(os, 'fork'),
@@ -37,7 +38,7 @@ def __init__(self, f, n, wait_before_exit=False):
3738
self.started = []
3839
self.finished = []
3940
self._can_exit = not wait_before_exit
40-
self.wait_thread = support.wait_threads_exit()
41+
self.wait_thread = threading_helper.wait_threads_exit()
4142
self.wait_thread.__enter__()
4243

4344
def task():
@@ -73,10 +74,10 @@ def do_finish(self):
7374

7475
class BaseTestCase(unittest.TestCase):
7576
def setUp(self):
76-
self._threads = support.threading_setup()
77+
self._threads = threading_helper.threading_setup()
7778

7879
def tearDown(self):
79-
support.threading_cleanup(*self._threads)
80+
threading_helper.threading_cleanup(*self._threads)
8081
support.reap_children()
8182

8283
def assertTimeout(self, actual, expected):
@@ -239,7 +240,7 @@ def f():
239240
lock.acquire()
240241
phase.append(None)
241242

242-
with support.wait_threads_exit():
243+
with threading_helper.wait_threads_exit():
243244
start_new_thread(f, ())
244245
while len(phase) == 0:
245246
_wait()

Lib/test/pickletester.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,9 @@
2929
from test import support
3030
from test.support import (
3131
TestFailed, TESTFN, run_with_locale, no_tracing,
32-
_2G, _4G, bigmemtest, reap_threads, forget,
32+
_2G, _4G, bigmemtest, forget,
3333
)
34+
from test.support import threading_helper
3435

3536
from pickle import bytes_types
3637

@@ -1350,7 +1351,7 @@ def test_truncated_data(self):
13501351
for p in badpickles:
13511352
self.check_unpickling_error(self.truncated_errors, p)
13521353

1353-
@reap_threads
1354+
@threading_helper.reap_threads
13541355
def test_unpickle_module_race(self):
13551356
# https://bugs.python.org/issue34572
13561357
locker_module = dedent("""

0 commit comments

Comments
 (0)