Skip to content

Commit 58f2c7f

Browse files
bpo-37526: Add support.catch_threading_exception() (GH-14664) (GH-14666)
Context manager catching threading.Thread exception using threading.excepthook. (cherry picked from commit 91b4f7a) Co-authored-by: Victor Stinner <vstinner@redhat.com>
1 parent c7be35c commit 58f2c7f

3 files changed

Lines changed: 92 additions & 0 deletions

File tree

Doc/library/test.rst

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1081,6 +1081,39 @@ The :mod:`test.support` module defines the following functions:
10811081
:exc:`PermissionError` is raised.
10821082

10831083

1084+
.. function:: catch_threading_exception()
1085+
1086+
Context manager catching :class:`threading.Thread` exception using
1087+
:func:`threading.excepthook`.
1088+
1089+
Attributes set when an exception is catched:
1090+
1091+
* ``exc_type``
1092+
* ``exc_value``
1093+
* ``exc_traceback``
1094+
* ``thread``
1095+
1096+
See :func:`threading.excepthook` documentation.
1097+
1098+
These attributes are deleted at the context manager exit.
1099+
1100+
Usage::
1101+
1102+
with support.catch_threading_exception() as cm:
1103+
# code spawning a thread which raises an exception
1104+
...
1105+
1106+
# check the thread exception, use cm attributes:
1107+
# exc_type, exc_value, exc_traceback, thread
1108+
...
1109+
1110+
# exc_type, exc_value, exc_traceback, thread attributes of cm no longer
1111+
# exists at this point
1112+
# (to avoid reference cycles)
1113+
1114+
.. versionadded:: 3.8
1115+
1116+
10841117
.. function:: catch_unraisable_exception()
10851118

10861119
Context manager catching unraisable exception using

Lib/test/support/__init__.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3157,3 +3157,60 @@ def __enter__(self):
31573157
def __exit__(self, *exc_info):
31583158
sys.unraisablehook = self._old_hook
31593159
del self.unraisable
3160+
3161+
3162+
class catch_threading_exception:
3163+
"""
3164+
Context manager catching threading.Thread exception using
3165+
threading.excepthook.
3166+
3167+
Attributes set when an exception is catched:
3168+
3169+
* exc_type
3170+
* exc_value
3171+
* exc_traceback
3172+
* thread
3173+
3174+
See threading.excepthook() documentation for these attributes.
3175+
3176+
These attributes are deleted at the context manager exit.
3177+
3178+
Usage:
3179+
3180+
with support.catch_threading_exception() as cm:
3181+
# code spawning a thread which raises an exception
3182+
...
3183+
3184+
# check the thread exception, use cm attributes:
3185+
# exc_type, exc_value, exc_traceback, thread
3186+
...
3187+
3188+
# exc_type, exc_value, exc_traceback, thread attributes of cm no longer
3189+
# exists at this point
3190+
# (to avoid reference cycles)
3191+
"""
3192+
3193+
def __init__(self):
3194+
self.exc_type = None
3195+
self.exc_value = None
3196+
self.exc_traceback = None
3197+
self.thread = None
3198+
self._old_hook = None
3199+
3200+
def _hook(self, args):
3201+
self.exc_type = args.exc_type
3202+
self.exc_value = args.exc_value
3203+
self.exc_traceback = args.exc_traceback
3204+
self.thread = args.thread
3205+
3206+
def __enter__(self):
3207+
self._old_hook = threading.excepthook
3208+
threading.excepthook = self._hook
3209+
return self
3210+
3211+
def __exit__(self, *exc_info):
3212+
threading.excepthook = self._old_hook
3213+
del self.exc_type
3214+
del self.exc_value
3215+
del self.exc_traceback
3216+
del self.thread
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Add :func:`test.support.catch_threading_exception`: context manager catching
2+
:class:`threading.Thread` exception using :func:`threading.excepthook`.

0 commit comments

Comments
 (0)