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.
Added the *max_group_width* and *max_group_depth* parameters.
+
:class:`StackSummary` Objects
-----------------------------
: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
=============
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)
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.
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__
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)
):
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)."""
--- /dev/null
+Add option to :func:`traceback.format_exception_only` to recurse into the
+nested exception of a :exc:`BaseExceptionGroup`.