Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
dgrisby opened this issue May 16, 2024 · 11 comments
Closed

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

dgrisby opened this issue May 16, 2024 · 11 comments
Labels
3.13 bugs and security fixes topic-repl Related to the interactive shell type-bug An unexpected behavior, bug, or error

Comments

@dgrisby
Copy link
Contributor

dgrisby commented May 16, 2024

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

@dgrisby dgrisby added the type-bug An unexpected behavior, bug, or error label May 16, 2024
@Eclips4 Eclips4 added the topic-repl Related to the interactive shell label May 16, 2024
@AlexWaygood AlexWaygood added the 3.13 bugs and security fixes label May 16, 2024
@danielhollas
Copy link
Contributor

danielhollas commented May 17, 2024

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.

@eugenetriguba
Copy link
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"?

@danielhollas
Copy link
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.

@danielhollas
Copy link
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)

@mi1acl
Copy link

mi1acl commented May 20, 2024

@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

@vstinner
Copy link
Member

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

@mi1acl
Copy link

mi1acl commented May 20, 2024

I can do this if it's ok

vstinner added a commit to vstinner/cpython that referenced this issue May 20, 2024
Move CAN_USE_PYREPL variable from _pyrepl.__main__ to _pyrepl and use
it in the site module to decide if _pyrepl.write_history_file() can
be used.
vstinner added a commit to vstinner/cpython that referenced this issue May 20, 2024
Move CAN_USE_PYREPL variable from _pyrepl.__main__ to _pyrepl and
rename it to _CAN_USE_PYREPL. Use the variable in the site module to
decide if _pyrepl.write_history_file() can be used.
vstinner added a commit to vstinner/cpython that referenced this issue May 20, 2024
Move CAN_USE_PYREPL variable from _pyrepl.__main__ to _pyrepl and
rename it to _CAN_USE_PYREPL. Use the variable in the site module to
decide if _pyrepl.write_history_file() can be used.
@vstinner
Copy link
Member

I proposed PR gh-119269 to fix this issue.

vstinner added a commit to vstinner/cpython that referenced this issue May 21, 2024
Use CAN_USE_PYREPL of _pyrepl.__main__ in the site module to decide
if _pyrepl.write_history_file() can be used.
vstinner added a commit that referenced this issue May 21, 2024
Use CAN_USE_PYREPL of _pyrepl.__main__ in the site module to decide
if _pyrepl.write_history_file() can be used.
miss-islington pushed a commit to miss-islington/cpython that referenced this issue May 21, 2024
Use CAN_USE_PYREPL of _pyrepl.__main__ in the site module to decide
if _pyrepl.write_history_file() can be used.
(cherry picked from commit 73f4a58)

Co-authored-by: Victor Stinner <vstinner@python.org>
vstinner added a commit that referenced this issue May 21, 2024
gh-119102: Fix REPL for dumb terminal (GH-119269)

Use CAN_USE_PYREPL of _pyrepl.__main__ in the site module to decide
if _pyrepl.write_history_file() can be used.
(cherry picked from commit 73f4a58)

Co-authored-by: Victor Stinner <vstinner@python.org>
@lysnikolaou
Copy link
Contributor

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

eugenetriguba added a commit to eugenetriguba/cpython that referenced this issue May 21, 2024
eugenetriguba added a commit to eugenetriguba/cpython that referenced this issue May 21, 2024
eugenetriguba added a commit to eugenetriguba/cpython that referenced this issue May 21, 2024
vstinner added a commit to vstinner/cpython that referenced this issue May 21, 2024
The site module gets the __main__ module to get _pyrepl.__main__.
vstinner added a commit to vstinner/cpython that referenced this issue May 21, 2024
The site module gets the __main__ module to get _pyrepl.__main__.
@vstinner
Copy link
Member

Please check my second fix: PR gh-119332.

vstinner added a commit that referenced this issue May 21, 2024
The site module gets the __main__ module to get _pyrepl.__main__.
miss-islington pushed a commit to miss-islington/cpython that referenced this issue May 21, 2024
The site module gets the __main__ module to get _pyrepl.__main__.
(cherry picked from commit de8f530)

Co-authored-by: Victor Stinner <vstinner@python.org>
lysnikolaou pushed a commit that referenced this issue May 22, 2024
The site module gets the __main__ module to get _pyrepl.__main__.
(cherry picked from commit de8f530)

Co-authored-by: Victor Stinner <vstinner@python.org>
@vstinner
Copy link
Member

This time, it should be fixed.

estyxx pushed a commit to estyxx/cpython that referenced this issue Jul 17, 2024
Use CAN_USE_PYREPL of _pyrepl.__main__ in the site module to decide
if _pyrepl.write_history_file() can be used.
estyxx pushed a commit to estyxx/cpython that referenced this issue Jul 17, 2024
The site module gets the __main__ module to get _pyrepl.__main__.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.13 bugs and security fixes topic-repl Related to the interactive shell type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

8 participants