Coverage for /home/crpier/Projects/snektest/snektest/presenter/traceback.py: 19%
36 statements
« prev ^ index » next coverage.py v7.14.1, created at 2026-06-07 00:30 +0300
« prev ^ index » next coverage.py v7.14.1, created at 2026-06-07 00:30 +0300
1import pathlib
2from collections.abc import Callable
3from types import TracebackType
5from rich.console import Console
6from rich.syntax import Syntax
8import snektest
11def render_traceback( # noqa: PLR0913
12 console: Console,
13 exc_type: type[BaseException],
14 exc_value: BaseException,
15 traceback: object,
16 *,
17 show_exception_line: bool = True,
18 open_path: Callable[[str], list[str]] | None = None,
19) -> None:
20 """Render a traceback without a box, using Rich for syntax highlighting."""
21 console.print("[bold]Traceback[/bold] [dim](most recent call last):[/dim]")
23 tb = traceback
24 snektest_path = str(snektest.__file__).rsplit("/", 1)[0]
26 while tb:
27 if not isinstance(tb, TracebackType):
28 break
30 frame = tb.tb_frame
31 lineno = tb.tb_lineno
32 filename = frame.f_code.co_filename
33 name = frame.f_code.co_name
35 if not filename.startswith(snektest_path):
36 console.print(
37 f' File "[cyan]{filename}[/cyan]", line {lineno}, in [yellow]{name}[/yellow]'
38 )
40 try:
41 if open_path is None:
42 with pathlib.Path(filename).open(encoding="utf-8") as f:
43 lines = f.readlines()
44 else:
45 lines = open_path(filename)
46 if 0 <= lineno - 1 < len(lines):
47 code_line = lines[lineno - 1].rstrip()
48 syntax = Syntax(
49 code_line,
50 "python",
51 theme="ansi_dark",
52 line_numbers=False,
53 padding=(0, 0, 0, 4),
54 )
55 console.print(syntax)
56 except (OSError, IndexError):
57 pass
59 tb = tb.tb_next
61 if not show_exception_line:
62 return
64 exc_name = exc_type.__name__
65 exc_msg = str(exc_value)
66 console.print(f"[red bold]{exc_name}[/red bold]: {exc_msg}")