← pod_r1_v1e

rich_3882

resolved RESOLVED PASS · 12 tool calls · 154 s · Textualize/rich

Task input

Fix raw markup printed on prompt errors sometimes

## Type of changes

- [x] Bug fix
- [ ] New feature
- [ ] Documentation / docstrings
- [ ] Tests
- [ ] Other

## Checklist

- [x] I've run the latest [black](https://github.com/psf/black) with default args on new code.
- [ ] I've updated CHANGELOG.md and CONTRIBUTORS.md where appropriate (see note about typos above).
- [x] I've added tests for new code.
- [x] I accept that @willmcgugan may be pedantic in the code review.

## Description

PromptBase.on_validate_error() should explicitly ask for markup in case the console passed to it has markup disabled globally.

Fixes #3881.

Tool calls (13)

#ToolArgumentsResult
1run_command
{
 "command": "grep -rn \"PromptBase\" . | grep \"on_validate_error\""
}
{"status": "error", "error_type": "CommandError", "error_message": "", "details": {"stdout": "", "stderr": "", "exit_code": 1}}
full
{"status": "error", "error_type": "CommandError", "error_message": "", "details": {"stdout": "", "stderr": "", "exit_code": 1}}
2run_command
{
 "command": "grep -rn \"on_validate_error\" ."
}
{"status": "ok", "stdout": "./rich/prompt.py:258: def on_validate_error(self, value: str, error: InvalidResponse) -> None:\n./rich/prompt.py:298: self.on_valida
full
{"status": "ok", "stdout": "./rich/prompt.py:258:    def on_validate_error(self, value: str, error: InvalidResponse) -> None:\n./rich/prompt.py:298:                self.on_validate_error(value, error)\n", "stderr": "", "exit_code": 0}
3run_command
{
 "command": "sed -n '250,270p' rich/prompt.py"
}
{"status": "ok", "stdout": " # return the original choice, not the lower case version\n return_value = self.response_type(\n self.choices[\n [choice.lower() for
full
{"status": "ok", "stdout": "                # return the original choice, not the lower case version\n                return_value = self.response_type(\n                    self.choices[\n                        [choice.lower() for choice in self.choices].index(value.lower())\n                    ]\n                )\n        return return_value\n\n    def on_validate_error(self, value: str, error: InvalidResponse) -> None:\n        \"\"\"Called to handle validation error.\n\n        Args:\n            value (str): String entered by user.\n            error (InvalidResponse): Exception instance the initiated the error.\n        \"\"\"\n        self.console.print(error)\n\n    def pre_prompt(self) -> None:\n        \"\"\"Hook to display something before the prompt.\"\"\"\n\n    @overload\n", "stderr": "", "exit_code": 0}
4run_command
{
 "command": "sed -n '258,265p' rich/prompt.py"
}
{"status": "ok", "stdout": " def on_validate_error(self, value: str, error: InvalidResponse) -> None:\n \"\"\"Called to handle validation error.\n\n Args:\n val
full
{"status": "ok", "stdout": "    def on_validate_error(self, value: str, error: InvalidResponse) -> None:\n        \"\"\"Called to handle validation error.\n\n        Args:\n            value (str): String entered by user.\n            error (InvalidResponse): Exception instance the initiated the error.\n        \"\"\"\n        self.console.print(error)\n", "stderr": "", "exit_code": 0}
5run_command
{
 "command": "python3 - <<'PY'\nfrom rich.console import Console\nfrom rich.prompt import Prompt\nfrom rich.errors import InvalidResponse\n\ndef test_markup_on_validate_error():\n    # Create a console with markup disabled\n    console = Console(markup=False)\n    prompt = Prompt(console=console)\n    \n    # Mock the validation error\n    error = InvalidResponse(\"[red]Error message[/red]\")\n    \n    # We want to see if on_validate_error prints the markup as raw text or as formatted text\n    # Since we can't easily capture the output of console.print in this script without redirecting stdout\n    # we will just check the behavior.\n    \n    print(\"Testing on_validate_error with markup=False console\")\n    prompt.on_validate_error(\"some value\", error)\n\ntest_markup_on_validate_error()\nPY\n"
}
{"status": "error", "error_type": "CommandError", "error_message": "Traceback (most recent call last):\n File \"<stdin>\", line 3, in <module>\nImportError: can
full
{"status": "error", "error_type": "CommandError", "error_message": "Traceback (most recent call last):\n  File \"<stdin>\", line 3, in <module>\nImportError: cannot import name 'InvalidResponse' from 'rich.errors' (/private/workspace/rich/errors.py)\n", "details": {"stdout": "", "stderr": "Traceback (most recent call last):\n  File \"<stdin>\", line 3, in <module>\nImportError: cannot import name 'InvalidResponse' from 'rich.errors' (/private/workspace/rich/errors.py)\n", "exit_code": 1}}
6run_command
{
 "command": "grep -rn \"class InvalidResponse\" ."
}
{"status": "ok", "stdout": "./rich/prompt.py:15:class InvalidResponse(PromptError):\n", "stderr": "", "exit_code": 0}
full
{"status": "ok", "stdout": "./rich/prompt.py:15:class InvalidResponse(PromptError):\n", "stderr": "", "exit_code": 0}
7run_command
{
 "command": "python3 - <<'PY'\nfrom rich.console import Console\nfrom rich.prompt import Prompt, InvalidResponse\nimport io\nfrom contextlib import redirect_stdout\n\ndef test_markup_on_validate_error():\n    # Create a console with markup disabled\n    console = Console(markup=False, force_terminal=False)\n    prompt = Prompt(console=console)\n    \n    # Mock the validation error\n    error = InvalidResponse(\"[red]Error message[/red]\")\n    \n    f = io.StringIO()\n    with redirect_stdout(f):\n        prompt.on_validate_error(\"some value\", error)\n    \n    output = f.getvalue()\n    print(f\"Output: {repr(output)}\")\n    # If markup is disabled, [red]Error message[/red] should be printed as is.\n    # If we want it to be rendered, we should pass markup=True to console.print.\n\ntest_markup_on_validate_error()\nPY\n"
}
{"status": "ok", "stdout": "Output: '[red]Error message[/red]\\n'\n", "stderr": "", "exit_code": 0}
full
{"status": "ok", "stdout": "Output: '[red]Error message[/red]\\n'\n", "stderr": "", "exit_code": 0}
8run_command
{
 "command": "python3 - <<'PY'\nfrom rich.console import Console\nfrom rich.prompt import Prompt, InvalidResponse\nimport io\nfrom contextlib import redirect_stdout\n\ndef test_markup_on_validate_error_fixed():\n    # Create a console with markup disabled\n    console = Console(markup=False, force_terminal=False)\n    prompt = Prompt(console=console)\n    \n    # Mock the validation error\n    error = InvalidResponse(\"[red]Error message[/red]\")\n    \n    f = io.StringIO()\n    with redirect_stdout(f):\n        # Simulate the fix: self.console.print(error, markup=True)\n        console.print(error, markup=True)\n    \n    output = f.getvalue()\n    print(f\"Output: {repr(output)}\")\n    # Now it should be rendered (ANSI codes for red) instead of raw markup.\n\ntest_markup_on_validate_error_fixed()\nPY\n"
}
{"status": "ok", "stdout": "Output: 'Error message\\n'\n", "stderr": "", "exit_code": 0}
full
{"status": "ok", "stdout": "Output: 'Error message\\n'\n", "stderr": "", "exit_code": 0}
9run_command
{
 "command": "cd /workspace && python3 - <<'PY'\nfrom pathlib import Path\np = Path(\"rich/prompt.py\"); s = p.read_text()\nold = \"\"\"    def on_validate_error(self, value: str, error: InvalidResponse) -> None:\n        \\\"\\\"\\\"Called to handle validation error.\n\n        Args:\n            value (str): String entered by user.\n            error (InvalidResponse): Exception instance the initiated the error.\n        \\\"\\\"\\\"\n        self.console.print(error)\"\"\"\nnew = \"\"\"    def on_validate_error(self, value: str, error: InvalidResponse) -> None:\n        \\\"\\\"\\\"Called to handle validation error.\n\n        Args:\n            value (str): String entered by user.\n            error (InvalidResponse): Exception instance the initiated the error.\n        \\\"\\\"\\\"\n        self.console.print(error, markup=True)\"\"\"\nassert s.count(old) == 1, (\"old text found this many times:\", s.count(old))\nt = s.replace(old, new); compile(t, str(p), \"exec\"); p.write_text(t)\nPY\n"
}
{"status": "ok", "stdout": "", "stderr": "", "exit_code": 0}
full
{"status": "ok", "stdout": "", "stderr": "", "exit_code": 0}
10run_command
{
 "command": "python3 - <<'PY'\nfrom rich.console import Console\nfrom rich.prompt import Prompt, InvalidResponse\nimport io\nfrom contextlib import redirect_stdout\n\ndef test_markup_on_validate_error():\n    # Create a console with markup disabled\n    console = Console(markup=False, force_terminal=False)\n    prompt = Prompt(console=console)\n    \n    # Mock the validation error\n    error = InvalidResponse(\"[red]Error message[/red]\")\n    \n    f = io.StringIO()\n    with redirect_stdout(f):\n        prompt.on_validate_error(\"some value\", error)\n    \n    output = f.getvalue()\n    print(f\"Output: {repr(output)}\")\n    # With markup=True in on_validate_error, it should NOT print [red]...[/red]\n    assert \"[red]\" not in output\n\ntest_markup_on_validate_error()\nPY\n"
}
{"status": "ok", "stdout": "Output: 'Error message\\n'\n", "stderr": "", "exit_code": 0}
full
{"status": "ok", "stdout": "Output: 'Error message\\n'\n", "stderr": "", "exit_code": 0}
11run_command
{
 "command": "git diff"
}
{"status": "ok", "stdout": "diff --git a/rich/prompt.py b/rich/prompt.py\nindex c7cf25ba..ae94d9bb 100644\n--- a/rich/prompt.py\n+++ b/rich/prompt.py\n@@ -262,7
full
{"status": "ok", "stdout": "diff --git a/rich/prompt.py b/rich/prompt.py\nindex c7cf25ba..ae94d9bb 100644\n--- a/rich/prompt.py\n+++ b/rich/prompt.py\n@@ -262,7 +262,7 @@ class PromptBase(Generic[PromptType]):\n             value (str): String entered by user.\n             error (InvalidResponse): Exception instance the initiated the error.\n         \"\"\"\n-        self.console.print(error)\n+        self.console.print(error, markup=True)\n \n     def pre_prompt(self) -> None:\n         \"\"\"Hook to display something before the prompt.\"\"\"\n", "stderr": "", "exit_code": 0}
12run_command
{
 "command": "submit_patch"
}
{"status": "error", "error_type": "CommandError", "error_message": "/bin/bash: submit_patch: command not found\n", "details": {"stdout": "", "stderr": "/bin/bas
full
{"status": "error", "error_type": "CommandError", "error_message": "/bin/bash: submit_patch: command not found\n", "details": {"stdout": "", "stderr": "/bin/bash: submit_patch: command not found\n", "exit_code": 127}}
13submit_patch
{}
{"status": "ok", "patch_size": 503, "files_changed": 1}
full
{"status": "ok", "patch_size": 503, "files_changed": 1}

Patch

diff --git a/rich/prompt.py b/rich/prompt.py
index c7cf25ba..ae94d9bb 100644
--- a/rich/prompt.py
+++ b/rich/prompt.py
@@ -262,7 +262,7 @@ class PromptBase(Generic[PromptType]):
             value (str): String entered by user.
             error (InvalidResponse): Exception instance the initiated the error.
         """
-        self.console.print(error)
+        self.console.print(error, markup=True)
 
     def pre_prompt(self) -> None:
         """Hook to display something before the prompt."""

Test output

show
........                                                                 [100%]
8 passed in 0.10s