summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIrit Katriel <1055913+iritkatriel@users.noreply.github.com>2023-06-06 09:26:18 (GMT)
committerGitHub <noreply@github.com>2023-06-06 09:26:18 (GMT)
commitf4d8e10d0d0cc1ba0787d2350a699d9fb227a7cd (patch)
treea529369faabe03a15219fec7c5793670d448d9a5
parent92022d8416d9e175800b65c4d71d4e4fb47adcb0 (diff)
downloadcpython-f4d8e10d0d0cc1ba0787d2350a699d9fb227a7cd.zip
cpython-f4d8e10d0d0cc1ba0787d2350a699d9fb227a7cd.tar.gz
cpython-f4d8e10d0d0cc1ba0787d2350a699d9fb227a7cd.tar.bz2
gh-105292: Add option to make traceback.TracebackException.format_exception_only recurse into exception groups (#105294)
Co-authored-by: Erlend E. Aasland <erlend.aasland@protonmail.com> Co-authored-by: Ɓukasz Langa <lukasz@langa.pl>
-rw-r--r--Doc/library/traceback.rst20
-rw-r--r--Doc/whatsnew/3.13.rst7
-rw-r--r--Lib/test/test_traceback.py14
-rw-r--r--Lib/traceback.py18
-rw-r--r--Misc/NEWS.d/next/Library/2023-06-04-23-20-56.gh-issue-105292.ns6XQR.rst2
5 files changed, 48 insertions, 13 deletions
diff --git a/Doc/library/traceback.rst b/Doc/library/traceback.rst
index 36171a3..3eb77fc 100644
--- a/Doc/library/traceback.rst
+++ b/Doc/library/traceback.rst
@@ -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
-----------------------------
diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst
index 4d47f24..3b19e96 100644
--- a/Doc/whatsnew/3.13.rst
+++ b/Doc/whatsnew/3.13.rst
@@ -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
=============
diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py
index 19a2be8..da7d1fb 100644
--- a/Lib/test/test_traceback.py
+++ b/Lib/test/test_traceback.py
@@ -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)
diff --git a/Lib/traceback.py b/Lib/traceback.py
index 21e3204..354754b 100644
--- a/Lib/traceback.py
+++ b/Lib/traceback.py
@@ -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
index 0000000..c23e1ff
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-06-04-23-20-56.gh-issue-105292.ns6XQR.rst
@@ -0,0 +1,2 @@
+Add option to :func:`traceback.format_exception_only` to recurse into the
+nested exception of a :exc:`BaseExceptionGroup`.