Skip to content

New pyrepl gives a traceback on exit with "dumb" terminal #119102

Description

@dgrisby

Bug report

Bug description:

I was experimenting with terminal types:

$ export TERM=dumb
$ python3
Python 3.13.0b1 (main, May 12 2024, 23:38:03) [GCC 13.2.1 20240316 (Red Hat 13.2.1-7)] on linux
Type "help", "copyright", "credits" or "license" for more information.
warning: can't use pyrepl: terminal doesn't have the required clear capability
>>> quit
Use quit() or Ctrl-D (i.e. EOF) to exit
>>> quit()
Exception ignored in atexit callback <function register_readline.<locals>.write_history at 0x7f7204f537e0>:
Traceback (most recent call last):
  File "<frozen site>", line 530, in write_history
  File "/home/duncan/py313inst/lib/python3.13/_pyrepl/readline.py", line 361, in write_history_file
    history = self.get_reader().get_trimmed_history(maxlength)
  File "/home/duncan/py313inst/lib/python3.13/_pyrepl/readline.py", line 277, in get_reader
    console = UnixConsole(self.f_in, self.f_out, encoding=ENCODING)
  File "/home/duncan/omni/py313inst/lib/python3.13/_pyrepl/unix_console.py", line 170, in __init__
    self._clear = _my_getstr("clear")
  File "/home/duncan/py313inst/lib/python3.13/_pyrepl/unix_console.py", line 163, in _my_getstr
    raise InvalidTerminal(
_pyrepl.unix_console.InvalidTerminal: terminal doesn't have the required clear capability

It notices that the terminal is unsuitable, but then tries to use it on exit.

CPython versions tested on:

3.13

Operating systems tested on:

Linux

Linked PRs

Activity

  1. danielhollas commented on May 17, 2024

    @danielhollas
    Contributor

    Looks like the write_history callback is registered in site.py here:

    def write_history():

            def write_history():
                try:
                    if os.getenv("PYTHON_BASIC_REPL"):
                        readline.write_history_file(history)
                    else:
                        _pyrepl.readline.write_history_file(history)
                except (FileNotFoundError, PermissionError):
                    # home directory does not exist or is not writable
                    # https://bugs.python.org/issue19891
                    pass

    It clearly needs to get more clever to detect whether pyrepl is actually in use.

    Maybe it can just look at the _pyrepl.__main__.CAN_USE_PYREPL global.

  2. eugenetriguba commented on May 20, 2024

    @eugenetriguba
    Contributor

    @danielhollas CAN_USE_PYREPL just checks whether we're on a Windows system, so I wouldn't think checking that would help in this case.

    Maybe: We set PYTHON_BASIC_REPL to true if TERM is set to "dumb"?

  3. danielhollas commented on May 20, 2024

    @danielhollas
    Contributor

    @eugenetriguba if you look at the _pyrepl/__main__.py, CAN_USE_PYREPL is indeed checking for windows at import, but then later it is set to False if for any reason the new repl cannot be used, on line 41.

    I tried to fix this by checking CAN_USE_PYREPL in the write_history callback function but couldn't make it work -- accessing CAN_USE_PYREPL from __main__ module seems to be cursed, and moving it to __init__ did not help.

  4. danielhollas commented on May 20, 2024

    @danielhollas
    Contributor

    Maybe: We set PYTHON_BASIC_REPL to true if TERM is set to "dumb"?

    The following patch indeed fixes the issue, happy to make a PR if this seems like a right approach

    diff --git a/Lib/_pyrepl/__main__.py b/Lib/_pyrepl/__main__.py
    index c598019e7c..40cdd6d9fe 100644
    --- a/Lib/_pyrepl/__main__.py
    +++ b/Lib/_pyrepl/__main__.py
    @@ -39,6 +39,7 @@ def interactive_console(mainmodule=None, quiet=False, pythonstartup=False):
             trace(msg)
             print(msg, file=sys.stderr)
             CAN_USE_PYREPL = False
    +        os.environ["PYTHON_BASIC_REPL"] = "true"
         if run_interactive is None:
             return sys._baserepl()
         return run_interactive(mainmodule)
  5. mi1acl commented on May 20, 2024

    @mi1acl

    @danielhollas I worked with @lysnikolaou during PyCon sprints on this one, we came to the same conclusion but he said this is not the best practice to export the env variable to the system. He said he will take a deeper look as to why this might be happening

  6. vstinner commented on May 20, 2024

    @vstinner
    Member

    Maybe add a site._CAN_USE_PYREPL constant and modify _pyrepl/__main__.py to set site._CAN_USE_PYREPL?

  7. mi1acl commented on May 20, 2024

    @mi1acl

    I can do this if it's ok

  8. added 3 commits that reference this issue on May 20, 2024
  9. vstinner commented on May 20, 2024

    @vstinner
    Member

    I proposed PR gh-119269 to fix this issue.

  10. added 2 commits that reference this issue on May 21, 2024
  11. added a commit that references this issue on May 21, 2024
  12. added a commit that references this issue on May 21, 2024
  13. lysnikolaou commented on May 21, 2024

    @lysnikolaou
    Member

    Leaving this open since #119269 did not fix the problem.

  14. added 2 commits that reference this issue on May 21, 2024
  15. vstinner commented on May 21, 2024

    @vstinner
    Member

    Please check my second fix: PR gh-119332.

  16. added a commit that references this issue on May 21, 2024
  17. added a commit that references this issue on May 21, 2024
  18. added a commit that references this issue on May 22, 2024
  19. vstinner commented on May 22, 2024

    @vstinner
    Member

    This time, it should be fixed.

  20. added 2 commits that reference this issue on Jul 17, 2024
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

    3.13only security fixestopic-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