bpo-42308: Add threading.__excepthook__ (GH-23218)

Add threading.__excepthook__ to allow retrieving the original value
of threading.excepthook in case it is set to a broken or a different
value.
This commit is contained in:
Mario Corchero 2020-11-12 18:27:44 +01:00 committed by GitHub
parent b5cc05bbe6
commit 750c5abf43
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 40 additions and 0 deletions

View File

@ -71,6 +71,13 @@ This module defines the following functions:
.. versionadded:: 3.8 .. versionadded:: 3.8
.. data:: __excepthook__
Holds the original value of :func:`threading.excepthook`. It is saved so that the
original value can be restored in case they happen to get replaced with
broken or alternative objects.
.. versionadded:: 3.10
.. function:: get_ident() .. function:: get_ident()

View File

@ -263,6 +263,11 @@ retrieve the functions set by :func:`threading.settrace` and
:func:`threading.setprofile` respectively. :func:`threading.setprofile` respectively.
(Contributed by Mario Corchero in :issue:`42251`.) (Contributed by Mario Corchero in :issue:`42251`.)
Add :data:`threading.__excepthook__` to allow retrieving the original value
of :func:`threading.excepthook` in case it is set to a broken or a different
value.
(Contributed by Mario Corchero in :issue:`42308`.)
traceback traceback
--------- ---------

View File

@ -1352,6 +1352,27 @@ class ExceptHookTests(BaseTestCase):
'Exception in threading.excepthook:\n') 'Exception in threading.excepthook:\n')
self.assertEqual(err_str, 'threading_hook failed') self.assertEqual(err_str, 'threading_hook failed')
def test_original_excepthook(self):
def run_thread():
with support.captured_output("stderr") as output:
thread = ThreadRunFail(name="excepthook thread")
thread.start()
thread.join()
return output.getvalue()
def threading_hook(args):
print("Running a thread failed", file=sys.stderr)
default_output = run_thread()
with support.swap_attr(threading, 'excepthook', threading_hook):
custom_hook_output = run_thread()
threading.excepthook = threading.__excepthook__
recovered_output = run_thread()
self.assertEqual(default_output, recovered_output)
self.assertNotEqual(default_output, custom_hook_output)
self.assertEqual(custom_hook_output, "Running a thread failed\n")
class TimerTests(BaseTestCase): class TimerTests(BaseTestCase):

View File

@ -1200,6 +1200,10 @@ except ImportError:
stderr.flush() stderr.flush()
# Original value of threading.excepthook
__excepthook__ = excepthook
def _make_invoke_excepthook(): def _make_invoke_excepthook():
# Create a local namespace to ensure that variables remain alive # Create a local namespace to ensure that variables remain alive
# when _invoke_excepthook() is called, even if it is called late during # when _invoke_excepthook() is called, even if it is called late during

View File

@ -0,0 +1,3 @@
Add :data:`threading.__excepthook__` to allow retrieving the original value
of :func:`threading.excepthook` in case it is set to a broken or a different
value. Patch by Mario Corchero.