Skip to content

Commit

Permalink
Display locals in traceback when requested
Browse files Browse the repository at this point in the history
By setting `TMT_SHOW_TRACEBACK` to `full`, tmt would dump locals for
each frame.
  • Loading branch information
happz committed May 17, 2024
1 parent f37da7d commit 56377a9
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 7 deletions.
2 changes: 2 additions & 0 deletions docs/overview.rst
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,8 @@ TMT_SHOW_TRACEBACK
By default, when tmt reports an error, the corresponding
traceback is not printed out. When ``TMT_SHOW_TRACEBACK`` is
set to any string except ``0``, traceback would be printed out.
When set to ``full``, traceback would list also local variables
in each stack frame.

TMT_OUTPUT_WIDTH
By default, the output width of commands like ``tmt * show`` is constrained
Expand Down
37 changes: 30 additions & 7 deletions tmt/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2466,6 +2466,35 @@ def render_run_exception(exception: RunError) -> Iterator[str]:
yield from render_run_exception_streams(exception.stdout, exception.stderr, verbose=verbose)


def render_exception_stack(exception: BaseException) -> Iterator[str]:
exception_traceback = traceback.TracebackException(
type(exception),
exception,
exception.__traceback__,
capture_locals=True)

# N806: allow upper-case names to make them look like formatting
# tags in strings below.
R = functools.partial(click.style, fg='red') # noqa: N806
Y = functools.partial(click.style, fg='yellow') # noqa: N806
B = functools.partial(click.style, fg='blue') # noqa: N806

yield R('Traceback (most recent call last):')
yield ''

for frame in exception_traceback.stack:
yield f'File {Y(frame.filename)}, line {Y(str(frame.lineno))}, in {Y(frame.name)}'
yield f' {B(frame.line)}'

if os.getenv('TMT_SHOW_TRACEBACK', '0').lower() == 'full' and frame.locals:
yield ''

for k, v in frame.locals.items():
yield f' {B(k)} = {Y(v)}'

yield ''


def render_exception(exception: BaseException) -> Iterator[str]:
""" Render the exception and its causes for printing """

Expand All @@ -2485,14 +2514,8 @@ def _indent(iterable: Iterable[str]) -> Iterator[str]:
yield from render_run_exception(exception)

if os.getenv('TMT_SHOW_TRACEBACK', '0') != '0':
formatted_exc = traceback.format_exception(
type(exception),
exception,
exception.__traceback__,
chain=False)

yield ''
yield from _indent(formatted_exc)
yield from _indent(render_exception_stack(exception))

# Follow the chain and render all causes
def _render_cause(number: int, cause: BaseException) -> Iterator[str]:
Expand Down

0 comments on commit 56377a9

Please sign in to comment.