[Python-checkins] gh-103176: sys._current_exceptions() returns mapping to exception instances instead of exc_info tuples (#103177)

iritkatriel webhook-mailer at python.org
Tue Apr 11 04:38:45 EDT 2023


https://github.com/python/cpython/commit/78b763f63032a7185c0905c319ead9e9b35787b6
commit: 78b763f63032a7185c0905c319ead9e9b35787b6
branch: main
author: Irit Katriel <1055913+iritkatriel at users.noreply.github.com>
committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com>
date: 2023-04-11T09:38:37+01:00
summary:

gh-103176: sys._current_exceptions() returns mapping to exception instances instead of exc_info tuples (#103177)

files:
A Misc/NEWS.d/next/Library/2023-04-01-23-01-31.gh-issue-103176.FBsdxa.rst
M Doc/library/sys.rst
M Doc/whatsnew/3.12.rst
M Lib/test/test_sys.py
M Python/pystate.c

diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst
index 00721efd1cf6..e37d57edce51 100644
--- a/Doc/library/sys.rst
+++ b/Doc/library/sys.rst
@@ -220,6 +220,10 @@ always available.
 
    .. audit-event:: sys._current_exceptions "" sys._current_exceptions
 
+   .. versionchanged:: 3.12
+      Each value in the dictionary is now a single exception instance, rather
+      than a 3-tuple as returned from ``sys.exc_info()``.
+
 .. function:: breakpointhook()
 
    This hook function is called by built-in :func:`breakpoint`.  By default,
diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst
index 651caed864fe..0eb16367267f 100644
--- a/Doc/whatsnew/3.12.rst
+++ b/Doc/whatsnew/3.12.rst
@@ -499,6 +499,10 @@ sys
   :data:`sys.last_type`, :data:`sys.last_value` and :data:`sys.last_traceback`.
   (Contributed by Irit Katriel in :gh:`102778`.)
 
+* :func:`sys._current_exceptions` now returns a mapping from thread-id to an
+  exception instance, rather than to a ``(typ, exc, tb)`` tuple.
+  (Contributed by Irit Katriel in :gh:`103176`.)
+
 
 Optimizations
 =============
@@ -940,6 +944,10 @@ Changes in the Python API
   synchronization is needed, implement locking within the cached property getter
   function or around multi-threaded access points.
 
+* :func:`sys._current_exceptions` now returns a mapping from thread-id to an
+  exception instance, rather than to a ``(typ, exc, tb)`` tuple.
+  (Contributed by Irit Katriel in :gh:`103176`.)
+
 
 Build Changes
 =============
diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py
index d7456d6d9480..890ffbf472c3 100644
--- a/Lib/test/test_sys.py
+++ b/Lib/test/test_sys.py
@@ -532,13 +532,13 @@ def g456():
             main_id = threading.get_ident()
             self.assertIn(main_id, d)
             self.assertIn(thread_id, d)
-            self.assertEqual((None, None, None), d.pop(main_id))
+            self.assertEqual(None, d.pop(main_id))
 
             # Verify that the captured thread frame is blocked in g456, called
             # from f123.  This is a little tricky, since various bits of
             # threading.py are also in the thread's call stack.
-            exc_type, exc_value, exc_tb = d.pop(thread_id)
-            stack = traceback.extract_stack(exc_tb.tb_frame)
+            exc_value = d.pop(thread_id)
+            stack = traceback.extract_stack(exc_value.__traceback__.tb_frame)
             for i, (filename, lineno, funcname, sourceline) in enumerate(stack):
                 if funcname == "f123":
                     break
diff --git a/Misc/NEWS.d/next/Library/2023-04-01-23-01-31.gh-issue-103176.FBsdxa.rst b/Misc/NEWS.d/next/Library/2023-04-01-23-01-31.gh-issue-103176.FBsdxa.rst
new file mode 100644
index 000000000000..b89f9bae5954
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-04-01-23-01-31.gh-issue-103176.FBsdxa.rst
@@ -0,0 +1,2 @@
+:func:`sys._current_exceptions` now returns a mapping from thread-id to an
+exception instance, rather than to a ``(typ, exc, tb)`` tuple.
diff --git a/Python/pystate.c b/Python/pystate.c
index d09c1d5743a4..37cef972e0fe 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -1986,14 +1986,13 @@ _PyThread_CurrentExceptions(void)
             if (id == NULL) {
                 goto fail;
             }
-            PyObject *exc_info = _PyErr_StackItemToExcInfoTuple(err_info);
-            if (exc_info == NULL) {
-                Py_DECREF(id);
-                goto fail;
-            }
-            int stat = PyDict_SetItem(result, id, exc_info);
+            PyObject *exc = err_info->exc_value;
+            assert(exc == NULL ||
+                   exc == Py_None ||
+                   PyExceptionInstance_Check(exc));
+
+            int stat = PyDict_SetItem(result, id, exc == NULL ? Py_None : exc);
             Py_DECREF(id);
-            Py_DECREF(exc_info);
             if (stat < 0) {
                 goto fail;
             }



More information about the Python-checkins mailing list