]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-103176: sys._current_exceptions() returns mapping to exception instances instead...
authorIrit Katriel <1055913+iritkatriel@users.noreply.github.com>
Tue, 11 Apr 2023 08:38:37 +0000 (09:38 +0100)
committerGitHub <noreply@github.com>
Tue, 11 Apr 2023 08:38:37 +0000 (09:38 +0100)
Doc/library/sys.rst
Doc/whatsnew/3.12.rst
Lib/test/test_sys.py
Misc/NEWS.d/next/Library/2023-04-01-23-01-31.gh-issue-103176.FBsdxa.rst [new file with mode: 0644]
Python/pystate.c

index 00721efd1cf65e1b6a8295bfb2bb5ce7805f4977..e37d57edce515f4beef82147d3279b12381a87e0 100644 (file)
@@ -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,
index 651caed864fef76b1faa119ac8caa59a27ffab47..0eb16367267f1c98b406be06603ef4b487834ca3 100644 (file)
@@ -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
 =============
index d7456d6d9480b299528a0cf1550d25fa6076934c..890ffbf472c33503e1b4b77dd84f09c110b281a6 100644 (file)
@@ -532,13 +532,13 @@ class SysModuleTest(unittest.TestCase):
             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 (file)
index 0000000..b89f9ba
--- /dev/null
@@ -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.
index d09c1d5743a4c652d99784a6c6e828b7176e7f9f..37cef972e0feb4a0af47ffd366595dd63e81efa3 100644 (file)
@@ -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;
             }