diff options
author | Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | 2019-07-09 11:35:59 (GMT) |
---|---|---|
committer | Victor Stinner <vstinner@redhat.com> | 2019-07-09 11:35:59 (GMT) |
commit | 58f2c7f424fe91ba035918f0f66306af73a37543 (patch) | |
tree | 8f1b17c13424a00d970ae7349caa66ebee9db96a | |
parent | c7be35c2abd598f02a633879133caec356593241 (diff) | |
download | cpython-58f2c7f424fe91ba035918f0f66306af73a37543.zip cpython-58f2c7f424fe91ba035918f0f66306af73a37543.tar.gz cpython-58f2c7f424fe91ba035918f0f66306af73a37543.tar.bz2 |
bpo-37526: Add support.catch_threading_exception() (GH-14664) (GH-14666)
Context manager catching threading.Thread exception using
threading.excepthook.
(cherry picked from commit 91b4f7ab7f9a5e0908b91379ee085ae087a76483)
Co-authored-by: Victor Stinner <vstinner@redhat.com>
-rw-r--r-- | Doc/library/test.rst | 33 | ||||
-rw-r--r-- | Lib/test/support/__init__.py | 57 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Tests/2019-07-09-12-33-18.bpo-37526.vmm5y7.rst | 2 |
3 files changed, 92 insertions, 0 deletions
diff --git a/Doc/library/test.rst b/Doc/library/test.rst index 920c018..7d62a94 100644 --- a/Doc/library/test.rst +++ b/Doc/library/test.rst @@ -1081,6 +1081,39 @@ The :mod:`test.support` module defines the following functions: :exc:`PermissionError` is raised. +.. function:: catch_threading_exception() + + Context manager catching :class:`threading.Thread` exception using + :func:`threading.excepthook`. + + Attributes set when an exception is catched: + + * ``exc_type`` + * ``exc_value`` + * ``exc_traceback`` + * ``thread`` + + See :func:`threading.excepthook` documentation. + + These attributes are deleted at the context manager exit. + + Usage:: + + with support.catch_threading_exception() as cm: + # code spawning a thread which raises an exception + ... + + # check the thread exception, use cm attributes: + # exc_type, exc_value, exc_traceback, thread + ... + + # exc_type, exc_value, exc_traceback, thread attributes of cm no longer + # exists at this point + # (to avoid reference cycles) + + .. versionadded:: 3.8 + + .. function:: catch_unraisable_exception() Context manager catching unraisable exception using diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 1c91fc4..a0fe086 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -3157,3 +3157,60 @@ class catch_unraisable_exception: def __exit__(self, *exc_info): sys.unraisablehook = self._old_hook del self.unraisable + + +class catch_threading_exception: + """ + Context manager catching threading.Thread exception using + threading.excepthook. + + Attributes set when an exception is catched: + + * exc_type + * exc_value + * exc_traceback + * thread + + See threading.excepthook() documentation for these attributes. + + These attributes are deleted at the context manager exit. + + Usage: + + with support.catch_threading_exception() as cm: + # code spawning a thread which raises an exception + ... + + # check the thread exception, use cm attributes: + # exc_type, exc_value, exc_traceback, thread + ... + + # exc_type, exc_value, exc_traceback, thread attributes of cm no longer + # exists at this point + # (to avoid reference cycles) + """ + + def __init__(self): + self.exc_type = None + self.exc_value = None + self.exc_traceback = None + self.thread = None + self._old_hook = None + + def _hook(self, args): + self.exc_type = args.exc_type + self.exc_value = args.exc_value + self.exc_traceback = args.exc_traceback + self.thread = args.thread + + def __enter__(self): + self._old_hook = threading.excepthook + threading.excepthook = self._hook + return self + + def __exit__(self, *exc_info): + threading.excepthook = self._old_hook + del self.exc_type + del self.exc_value + del self.exc_traceback + del self.thread diff --git a/Misc/NEWS.d/next/Tests/2019-07-09-12-33-18.bpo-37526.vmm5y7.rst b/Misc/NEWS.d/next/Tests/2019-07-09-12-33-18.bpo-37526.vmm5y7.rst new file mode 100644 index 0000000..aff6b6d --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2019-07-09-12-33-18.bpo-37526.vmm5y7.rst @@ -0,0 +1,2 @@ +Add :func:`test.support.catch_threading_exception`: context manager catching +:class:`threading.Thread` exception using :func:`threading.excepthook`. |