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

1import pathlib 

2from collections.abc import Callable 

3from types import TracebackType 

4 

5from rich.console import Console 

6from rich.syntax import Syntax 

7 

8import snektest 

9 

10 

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]") 

22 

23 tb = traceback 

24 snektest_path = str(snektest.__file__).rsplit("/", 1)[0] 

25 

26 while tb: 

27 if not isinstance(tb, TracebackType): 

28 break 

29 

30 frame = tb.tb_frame 

31 lineno = tb.tb_lineno 

32 filename = frame.f_code.co_filename 

33 name = frame.f_code.co_name 

34 

35 if not filename.startswith(snektest_path): 

36 console.print( 

37 f' File "[cyan]{filename}[/cyan]", line {lineno}, in [yellow]{name}[/yellow]' 

38 ) 

39 

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 

58 

59 tb = tb.tb_next 

60 

61 if not show_exception_line: 

62 return 

63 

64 exc_name = exc_type.__name__ 

65 exc_msg = str(exc_value) 

66 console.print(f"[red bold]{exc_name}[/red bold]: {exc_msg}")