Skip to content

Fall back to repr() when __pt_repr__ yields malformed fragments - #632

Open
chiliec wants to merge 1 commit into
prompt-toolkit:mainfrom
chiliec:fix/issue-610-malformed-pt-repr-fragments
Open

Fall back to repr() when __pt_repr__ yields malformed fragments#632
chiliec wants to merge 1 commit into
prompt-toolkit:mainfrom
chiliec:fix/issue-610-malformed-pt-repr-fragments

Conversation

@chiliec

@chiliec chiliec commented Aug 27, 2026

Copy link
Copy Markdown

Fixes #610.

Problem

Inspecting a unittest.mock.MagicMock result crashes the REPL:

>>> from unittest.mock import MagicMock
>>> m = MagicMock()
>>> m.get()
>>> m.method_calls[0]
Traceback (most recent call last):
  ...
  File ".../prompt_toolkit/formatted_text/utils.py", line 88, in split_lines
    for style, string, *mouse_handler in fragments:
ValueError: not enough values to unpack (expected at least 2, got 0)

Root cause

In OutputPrinter._format_result_output, a result carrying __pt_repr__ is trusted to return prompt_toolkit formatted text. A MagicMock fabricates any attribute, so hasattr(result, "__pt_repr__") is True; calling it returns further mocks, and to_formatted_text(...) then produces a malformed fragment list such as:

FormattedText(["__pt_repr__().__pt_formatted_text__", (), {}])

The empty tuple () has no (style, text) to unpack, so the later split_lines pass raises ValueError.

Fix

After building the formatted text from __pt_repr__, verify that every fragment is a well-formed (style, text, …) tuple before yielding it. If any fragment is malformed, fall through to the normal repr() path (which lexes call.get() into valid fragments). This keeps __pt_repr__ support intact for well-behaved objects and only guards against fabricated / broken implementations.

Test

Adds tests/test_printer.py, which feeds MagicMock().method_calls[0] through _format_result_output and asserts the fragments are all valid tuples, split_lines does not raise, and the rendered text is the object’s repr.

Verification (local, Python 3.11)

  • RED→GREEN: with the fix reverted, the new test fails (the fabricated fragment is not a tuple); with the fix it passes.
  • Full test suite passes (pytest), and ruff check on the changed files is clean.

Inspecting a unittest.mock.MagicMock result (e.g. m.method_calls[0]) crashed
the REPL with 'ValueError: not enough values to unpack (expected at least 2,
got 0)'. A MagicMock fabricates any attribute, so hasattr(result,
'__pt_repr__') is True; calling it returns more mocks, and to_formatted_text
then produces malformed fragments such as an empty tuple, which split_lines
later fails to unpack.

Validate that every fragment from __pt_repr__ is a well-formed (style, text)
tuple before trusting it; otherwise fall through to the normal repr() path.

Adds a regression test.

Fixes prompt-toolkit#610.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Unhandled 'ValueError: not enough values to unpack' when inspecting MagicMock.method_calls

1 participant