[Python-checkins] bpo-42308: Add threading.__excepthook__ (GH-23218)

vstinner webhook-mailer at python.org
Thu Nov 12 12:27:52 EST 2020


https://github.com/python/cpython/commit/750c5abf43b7b1627ab59ead237bef4c2314d29e
commit: 750c5abf43b7b1627ab59ead237bef4c2314d29e
branch: master
author: Mario Corchero <mcorcherojim at bloomberg.net>
committer: vstinner <vstinner at python.org>
date: 2020-11-12T18:27:44+01:00
summary:

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.

files:
A Misc/NEWS.d/next/Library/2020-11-10-12-09-13.bpo-42308.yaJHH9.rst
M Doc/library/threading.rst
M Doc/whatsnew/3.10.rst
M Lib/test/test_threading.py
M Lib/threading.py

diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst
index e05486f7d0849..690735469d0bf 100644
--- a/Doc/library/threading.rst
+++ b/Doc/library/threading.rst
@@ -71,6 +71,13 @@ This module defines the following functions:
 
    .. 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()
 
diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst
index 74c1c28ec0ff3..4d772005581ad 100644
--- a/Doc/whatsnew/3.10.rst
+++ b/Doc/whatsnew/3.10.rst
@@ -263,6 +263,11 @@ retrieve the functions set by :func:`threading.settrace` and
 :func:`threading.setprofile` respectively.
 (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
 ---------
 
diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py
index e0e5406ac26a1..db440d42f816d 100644
--- a/Lib/test/test_threading.py
+++ b/Lib/test/test_threading.py
@@ -1352,6 +1352,27 @@ def sys_hook(exc_type, exc_value, exc_traceback):
                          'Exception in threading.excepthook:\n')
         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):
 
diff --git a/Lib/threading.py b/Lib/threading.py
index d4fe649e4f04b..7dae77dfd4da2 100644
--- a/Lib/threading.py
+++ b/Lib/threading.py
@@ -1200,6 +1200,10 @@ def excepthook(args, /):
         stderr.flush()
 
 
+# Original value of threading.excepthook
+__excepthook__ = excepthook
+
+
 def _make_invoke_excepthook():
     # Create a local namespace to ensure that variables remain alive
     # when _invoke_excepthook() is called, even if it is called late during
diff --git a/Misc/NEWS.d/next/Library/2020-11-10-12-09-13.bpo-42308.yaJHH9.rst b/Misc/NEWS.d/next/Library/2020-11-10-12-09-13.bpo-42308.yaJHH9.rst
new file mode 100644
index 0000000000000..3460b0c92b150
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2020-11-10-12-09-13.bpo-42308.yaJHH9.rst
@@ -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.



More information about the Python-checkins mailing list