]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-105292: Add option to make traceback.TracebackException.format_exception_only...
authorIrit Katriel <1055913+iritkatriel@users.noreply.github.com>
Tue, 6 Jun 2023 09:26:18 +0000 (10:26 +0100)
committerGitHub <noreply@github.com>
Tue, 6 Jun 2023 09:26:18 +0000 (11:26 +0200)
Co-authored-by: Erlend E. Aasland <erlend.aasland@protonmail.com>
Co-authored-by: Ɓukasz Langa <lukasz@langa.pl>
Doc/library/traceback.rst
Doc/whatsnew/3.13.rst
Lib/test/test_traceback.py
Lib/traceback.py
Misc/NEWS.d/next/Library/2023-06-04-23-20-56.gh-issue-105292.ns6XQR.rst [new file with mode: 0644]

index 36171a3b5a610d0d8e0d2256f83af11c2f9c78d4..3eb77fc3df57099e90b46957848812d026476649 100644 (file)
@@ -333,19 +333,24 @@ capture data for later printing in a lightweight fashion.
       The message indicating which exception occurred is always the last
       string in the output.
 
-   .. method::  format_exception_only()
+   .. method::  format_exception_only(*, show_group=False)
 
       Format the exception part of the traceback.
 
       The return value is a generator of strings, each ending in a newline.
 
-      Normally, the generator emits a single string; however, for
-      :exc:`SyntaxError` exceptions, it emits several lines that (when
-      printed) display detailed information about where the syntax
-      error occurred.
+      When *show_group* is ``False``, the generator normally emits a single
+      string; however, for :exc:`SyntaxError` exceptions, it emits several
+      lines that (when printed) display detailed information about where
+      the syntax error occurred.  The message indicating which exception
+      occurred is always the last string in the output.
 
-      The message indicating which exception occurred is always the last
-      string in the output.
+      When *show_group* is ``True``, and the exception is an instance of
+      :exc:`BaseExceptionGroup`, the nested exceptions are included as
+      well, recursively, with indentation relative to their nesting depth.
+
+      .. versionchanged:: 3.13
+         Added the *show_group* parameter.
 
    .. versionchanged:: 3.10
       Added the *compact* parameter.
@@ -354,6 +359,7 @@ capture data for later printing in a lightweight fashion.
       Added the *max_group_width* and *max_group_depth* parameters.
 
 
+
 :class:`StackSummary` Objects
 -----------------------------
 
index 4d47f24eea7bd91003cf4e1d9e7ad65bebd15d7d..3b19e96719a6d2347c2961bf6df16be5ee746998 100644 (file)
@@ -113,6 +113,13 @@ pathlib
   :meth:`~pathlib.Path.rglob`.
   (Contributed by Barney Gale in :gh:`77609`.)
 
+traceback
+---------
+
+* Add *show_group* paramter to :func:`traceback.TracebackException.format_exception_only`
+  to format the nested exceptions of a :exc:`BaseExceptionGroup` instance, recursively.
+  (Contributed by Irit Katriel in :gh:`105292`.)
+
 Optimizations
 =============
 
index 19a2be88d2c1bc98f235af671d7f17a90af43a02..da7d1fb559203eca30fbbabc13e76f395ce55558 100644 (file)
@@ -2792,6 +2792,20 @@ class TestTracebackException_ExceptionGroups(unittest.TestCase):
 
         self.assertEqual(formatted, expected)
 
+    def test_exception_group_format_exception_onlyi_recursive(self):
+        teg = traceback.TracebackException.from_exception(self.eg)
+        formatted = ''.join(teg.format_exception_only(show_group=True)).split('\n')
+        expected = [
+                     'ExceptionGroup: eg2 (2 sub-exceptions)',
+                     '   ExceptionGroup: eg1 (2 sub-exceptions)',
+                     '      ZeroDivisionError: division by zero',
+                     '      ValueError: 42',
+                     '   ValueError: 24',
+                     ''
+                   ]
+
+        self.assertEqual(formatted, expected)
+
     def test_exception_group_format(self):
         teg = traceback.TracebackException.from_exception(self.eg)
 
index 21e32040ee9872243dd2ea1f7cc2748f61e45528..354754b9560a19dad590247c8460c5a782028a4d 100644 (file)
@@ -826,7 +826,7 @@ class TracebackException:
     def __str__(self):
         return self._str
 
-    def format_exception_only(self):
+    def format_exception_only(self, *, show_group=False, _depth=0):
         """Format the exception part of the traceback.
 
         The return value is a generator of strings, each ending in a newline.
@@ -839,8 +839,10 @@ class TracebackException:
         The message indicating which exception occurred is always the last
         string in the output.
         """
+
+        indent = 3 * _depth * ' '
         if self.exc_type is None:
-            yield _format_final_exc_line(None, self._str)
+            yield indent + _format_final_exc_line(None, self._str)
             return
 
         stype = self.exc_type.__qualname__
@@ -851,9 +853,9 @@ class TracebackException:
             stype = smod + '.' + stype
 
         if not issubclass(self.exc_type, SyntaxError):
-            yield _format_final_exc_line(stype, self._str)
+            yield indent + _format_final_exc_line(stype, self._str)
         else:
-            yield from self._format_syntax_error(stype)
+            yield from [indent + l for l in self._format_syntax_error(stype)]
 
         if (
             isinstance(self.__notes__, collections.abc.Sequence)
@@ -861,9 +863,13 @@ class TracebackException:
         ):
             for note in self.__notes__:
                 note = _safe_string(note, 'note')
-                yield from [l + '\n' for l in note.split('\n')]
+                yield from [indent + l + '\n' for l in note.split('\n')]
         elif self.__notes__ is not None:
-            yield "{}\n".format(_safe_string(self.__notes__, '__notes__', func=repr))
+            yield indent + "{}\n".format(_safe_string(self.__notes__, '__notes__', func=repr))
+
+        if self.exceptions and show_group:
+            for ex in self.exceptions:
+                yield from ex.format_exception_only(show_group=show_group, _depth=_depth+1)
 
     def _format_syntax_error(self, stype):
         """Format SyntaxError exceptions (internal helper)."""
diff --git a/Misc/NEWS.d/next/Library/2023-06-04-23-20-56.gh-issue-105292.ns6XQR.rst b/Misc/NEWS.d/next/Library/2023-06-04-23-20-56.gh-issue-105292.ns6XQR.rst
new file mode 100644 (file)
index 0000000..c23e1ff
--- /dev/null
@@ -0,0 +1,2 @@
+Add option to :func:`traceback.format_exception_only` to recurse into the
+nested exception of a :exc:`BaseExceptionGroup`.