Skip to content

Exception raised in traceback.StackSummary._should_show_carets exits interpreter: IndexError on tree.body[0] #122145

Closed
@devdanzin

Description

@devdanzin

Bug report

Bug description:

Running the code sample from #122071 in 3.13.0b4 or main exits the interpreter due to traceback.StackSummary._should_show_carets raising an exception:

>>> exec(compile("tuple()[0]", "s", "exec"))
Traceback (most recent call last):
Exception ignored in the internal traceback machinery:
Traceback (most recent call last):
  File "~\PycharmProjects\cpython\Lib\traceback.py", line 139, in _print_exception_bltin
    return print_exception(exc, limit=BUILTIN_EXCEPTION_LIMIT, file=file, colorize=colorize)
  File "~\PycharmProjects\cpython\Lib\traceback.py", line 130, in print_exception
    te.print(file=file, chain=chain, colorize=colorize)
  File "~\PycharmProjects\cpython\Lib\traceback.py", line 1448, in print
    for line in self.format(chain=chain, colorize=colorize):
  File "~\PycharmProjects\cpython\Lib\traceback.py", line 1384, in format
    yield from _ctx.emit(exc.stack.format(colorize=colorize))
  File "~\PycharmProjects\cpython\Lib\traceback.py", line 747, in format
    formatted_frame = self.format_frame_summary(frame_summary, colorize=colorize)
  File "~\PycharmProjects\cpython\Lib\traceback.py", line 583, in format_frame_summary
    show_carets = self._should_show_carets(start_offset, end_offset, all_lines, anchors)
  File "~\PycharmProjects\cpython\Lib\traceback.py", line 701, in _should_show_carets
    statement = tree.body[0]
IndexError: list index out of range
Traceback (most recent call last):
  File "~\PycharmProjects\cpython\Lib\code.py", line 91, in runcode
    exec(code, self.locals)
  File "<python-input-2>", line 1, in <module>
  File "s", line 1, in <module>
IndexError: tuple index out of range

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "~\PycharmProjects\cpython\Lib\runpy.py", line 198, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "~\PycharmProjects\cpython\Lib\runpy.py", line 88, in _run_code
    exec(code, run_globals)
  File "~\PycharmProjects\cpython\Lib\_pyrepl\__main__.py", line 6, in <module>
    __pyrepl_interactive_console()
  File "~\PycharmProjects\cpython\Lib\_pyrepl\main.py", line 59, in interactive_console
    run_multiline_interactive_console(console)
  File "~\PycharmProjects\cpython\Lib\_pyrepl\simple_interact.py", line 156, in run_multiline_interactive_console
    more = console.push(_strip_final_indent(statement), filename=input_name, _symbol="single")  # type: ignore[call-arg]
  File "~\PycharmProjects\cpython\Lib\code.py", line 303, in push
    more = self.runsource(source, filename, symbol=_symbol)
  File "~\PycharmProjects\cpython\Lib\_pyrepl\console.py", line 200, in runsource
    self.runcode(code)
  File "~\PycharmProjects\cpython\Lib\code.py", line 95, in runcode
    self.showtraceback()
  File "~\PycharmProjects\cpython\Lib\_pyrepl\console.py", line 168, in showtraceback
    super().showtraceback(colorize=self.can_colorize)
  File "~\PycharmProjects\cpython\Lib\code.py", line 147, in showtraceback
    lines = traceback.format_exception(ei[0], ei[1], last_tb.tb_next, colorize=colorize)
  File "~\PycharmProjects\cpython\Lib\traceback.py", line 155, in format_exception
    return list(te.format(chain=chain, colorize=colorize))
  File "~\PycharmProjects\cpython\Lib\traceback.py", line 1384, in format
    yield from _ctx.emit(exc.stack.format(colorize=colorize))
  File "~\PycharmProjects\cpython\Lib\traceback.py", line 747, in format
    formatted_frame = self.format_frame_summary(frame_summary, colorize=colorize)
  File "~\PycharmProjects\cpython\Lib\traceback.py", line 583, in format_frame_summary
    show_carets = self._should_show_carets(start_offset, end_offset, all_lines, anchors)
  File "~\PycharmProjects\cpython\Lib\traceback.py", line 701, in _should_show_carets
    statement = tree.body[0]
IndexError: list index out of range
[Thread 31424.0x8ec0 exited with code 1]
[Thread 31424.0x15dc exited with code 1]
[Thread 31424.0x8b8c exited with code 1]
[Inferior 1 (process 31424) exited with code 01]

We can either protect the _should_show_carets call with suppress(Exception) here:

cpython/Lib/traceback.py

Lines 581 to 583 in 2762c6c

with suppress(Exception):
anchors = _extract_caret_anchors_from_line_segment(segment)
show_carets = self._should_show_carets(start_offset, end_offset, all_lines, anchors)

Or guard against tree.body being empty here:

cpython/Lib/traceback.py

Lines 700 to 701 in 2762c6c

tree = ast.parse('\n'.join(all_lines))
statement = tree.body[0]

(or both?)

Should I submit a PR with one of the fixes above? Any preferences?

CPython versions tested on:

3.13, CPython main branch

Operating systems tested on:

Windows, Linux

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    type-bugAn unexpected behavior, bug, or error

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions