summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMario Corchero <mcorcherojim@bloomberg.net>2020-11-12 17:27:44 (GMT)
committerGitHub <noreply@github.com>2020-11-12 17:27:44 (GMT)
commit750c5abf43b7b1627ab59ead237bef4c2314d29e (patch)
treef8ebda9718f8e2b5c7a564a7aaae0e4170639360
parentb5cc05bbe681dbe06d5ec6d34318815d1c1ad6c5 (diff)
downloadcpython-750c5abf43b7b1627ab59ead237bef4c2314d29e.zip
cpython-750c5abf43b7b1627ab59ead237bef4c2314d29e.tar.gz
cpython-750c5abf43b7b1627ab59ead237bef4c2314d29e.tar.bz2
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.
-rw-r--r--Doc/library/threading.rst7
-rw-r--r--Doc/whatsnew/3.10.rst5
-rw-r--r--Lib/test/test_threading.py21
-rw-r--r--Lib/threading.py4
-rw-r--r--Misc/NEWS.d/next/Library/2020-11-10-12-09-13.bpo-42308.yaJHH9.rst3
5 files changed, 40 insertions, 0 deletions
diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst
index e05486f..6907354 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 74c1c28..4d77200 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 e0e5406..db440d4 100644
--- a/Lib/test/test_threading.py
+++ b/Lib/test/test_threading.py
@@ -1352,6 +1352,27 @@ class ExceptHookTests(BaseTestCase):
'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 d4fe649..7dae77d 100644
--- a/Lib/threading.py
+++ b/Lib/threading.py
@@ -1200,6 +1200,10 @@ except ImportError:
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 0000000..3460b0c
--- /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.