Skip to content

REPL exits with traceback when str(sys.ps1) raises #130698

Description

@gvanrossum

Bug report

Bug description:

Subject says it all. This is on the latest HEAD of main.

~/cpython$ g pull
Already up to date.
~/cpython$ make
Checked 112 modules (34 built-in, 78 shared, 0 n/a on macosx-14.6-x86_64, 0 disabled, 0 missing, 0 failed on import)
./python.exe -E ./Tools/build/generate-build-details.py `cat pybuilddir.txt`/build-details.json
~/cpython$ ./python.exe 
Python 3.14.0a5+ (heads/main:ab11c097052, Feb 28 2025, 08:56:47) [Clang 16.0.0 (clang-1600.0.26.6)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> class C:
...     def __str__(self): 1/0
...     
>>> sys.ps1 = C()
Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "/Users/guido/cpython/Lib/_pyrepl/__main__.py", line 6, in <module>
    __pyrepl_interactive_console()
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/Users/guido/cpython/Lib/_pyrepl/main.py", line 59, in interactive_console
    run_multiline_interactive_console(console)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^
  File "/Users/guido/cpython/Lib/_pyrepl/simple_interact.py", line 143, in run_multiline_interactive_console
    statement = multiline_input(more_lines, ps1, ps2)
  File "/Users/guido/cpython/Lib/_pyrepl/readline.py", line 389, in multiline_input
    return reader.readline()
           ~~~~~~~~~~~~~~~^^
  File "/Users/guido/cpython/Lib/_pyrepl/reader.py", line 796, in readline
    self.prepare()
    ~~~~~~~~~~~~^^
  File "/Users/guido/cpython/Lib/_pyrepl/historical_reader.py", line 306, in prepare
    super().prepare()
    ~~~~~~~~~~~~~~~^^
  File "/Users/guido/cpython/Lib/_pyrepl/reader.py", line 643, in prepare
    self.calc_screen()
    ~~~~~~~~~~~~~~~~^^
  File "/Users/guido/cpython/Lib/_pyrepl/completing_reader.py", line 261, in calc_screen
    screen = super().calc_screen()
  File "/Users/guido/cpython/Lib/_pyrepl/reader.py", line 371, in calc_screen
    prompt = self.get_prompt(ln, ll >= pos >= 0)
  File "/Users/guido/cpython/Lib/_pyrepl/historical_reader.py", line 326, in get_prompt
    return super().get_prompt(lineno, cursor_on_line)
           ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/guido/cpython/Lib/_pyrepl/reader.py", line 552, in get_prompt
    prompt = f"{ANSIColors.BOLD_MAGENTA}{prompt}{ANSIColors.RESET}"
                                        ^^^^^^^^
  File "<python-input-1>", line 2, in __str__
    def __str__(self): 1/0
                       ~^~
ZeroDivisionError: division by zero
~/cpython$ 

Probably @pablogsal should look into this.

CPython versions tested on:

CPython main branch

Operating systems tested on:

macOS

Linked PRs

Activity

  1. added
    stdlibStandard Library Python modules in the Lib/ directory
    topic-replRelated to the interactive shell
    on Feb 28, 2025
  2. pablogsal commented on Feb 28, 2025

    @pablogsal
    Member
  3. sergey-miryanov commented on Feb 28, 2025

    @sergey-miryanov
    Contributor

    Easy fix is

    git diff
    diff --git a/Lib/_pyrepl/reader.py b/Lib/_pyrepl/reader.py
    index 1252847e02b..6d41802bce0 100644
    --- a/Lib/_pyrepl/reader.py
    +++ b/Lib/_pyrepl/reader.py
    @@ -548,6 +548,11 @@ def get_prompt(self, lineno: int, cursor_on_line: bool) -> str:
             else:
                 prompt = self.ps1
    
    +        try:
    +            prompt = str(prompt)
    +        except:
    +            prompt = ">>> "
    +
             if self.can_colorize:
                 prompt = f"{ANSIColors.BOLD_MAGENTA}{prompt}{ANSIColors.RESET}"
             return prompt
    

    But maybe we should handle unrecoverable exceptions like MemoryError, SystemExit and stop REPL?

  4. pablogsal commented on Mar 10, 2025

    @pablogsal
    Member

    @sergey-miryanov wanna prepare a PR for this @sergey-miryanov ?

  5. sergey-miryanov commented on Mar 11, 2025

    @sergey-miryanov
    Contributor

    @pablogsal yes, will do.

  6. added a commit that references this issue on Mar 11, 2025
  7. sergey-miryanov commented on Mar 11, 2025

    @sergey-miryanov
    Contributor

    @pablogsal I just have added a PR. Please take a look.

  8. skirpichev commented on Apr 19, 2025

    @skirpichev
    Member

    Note that old repl just clear error indicator and return empty prompt:

    cpython/Python/pythonrun.c

    Lines 228 to 237 in 8a9c6c4

    const char *ps1 = "";
    if (_PySys_GetOptionalAttr(&_Py_ID(ps1), &attr) < 0) {
    PyErr_Clear();
    }
    else if (attr != NULL) {
    ps1_obj = PyObject_Str(attr);
    Py_DECREF(attr);
    if (ps1_obj == NULL) {
    PyErr_Clear();
    }

    But maybe we should handle unrecoverable exceptions like MemoryError, SystemExit and stop REPL?

    MemoryError isn't really unrecoverable, unless you have some bug in your C code. The SystemExit is more questionable.

    I think it's ok to replicate old-repl behavior, but instead of being just silent - emit a warning.

  9. added 2 commits that reference this issue on Apr 19, 2025
  10. sergey-miryanov commented on Apr 19, 2025

    @sergey-miryanov
    Contributor

    @skirpichev I don't know what is the best way - replicate old behavior, show default prompt (as I did in PR), or emit warning. Maybe @pablogsal can point to the right direction.

  11. added 2 commits that reference this issue on Jun 13, 2025
  12. added a commit that references this issue on Nov 1, 2025
  13. added a commit that references this issue on Nov 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibStandard Library Python modules in the Lib/ directorytopic-replRelated to the interactive shelltype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions