Skip to content

Commit

Permalink
gh-125096: Don't import _pyrepl in site if PYTHON_BASIC_REPL (#125097)
Browse files Browse the repository at this point in the history
If the PYTHON_BASIC_REPL environment variable is set, the site module
no longer imports the _pyrepl module.

Moreover, the site module now respects -E and -I command line
options: ignore PYTHON_BASIC_REPL in this case.
  • Loading branch information
vstinner authored Oct 8, 2024
1 parent 5967dd8 commit 65ce228
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 7 deletions.
26 changes: 19 additions & 7 deletions Lib/site.py
Original file line number Diff line number Diff line change
Expand Up @@ -491,12 +491,21 @@ def register_readline():
This can be overridden in the sitecustomize or usercustomize module,
or in a PYTHONSTARTUP file.
"""
if not sys.flags.ignore_environment:
PYTHON_BASIC_REPL = os.getenv("PYTHON_BASIC_REPL")
else:
PYTHON_BASIC_REPL = False

import atexit
try:
import readline
import rlcompleter # noqa: F401
import _pyrepl.readline
import _pyrepl.unix_console
if PYTHON_BASIC_REPL:
CAN_USE_PYREPL = False
else:
import _pyrepl.readline
import _pyrepl.unix_console
from _pyrepl.main import CAN_USE_PYREPL
except ImportError:
return

Expand All @@ -517,21 +526,24 @@ def register_readline():
pass

if readline.get_current_history_length() == 0:
from _pyrepl.main import CAN_USE_PYREPL
# If no history was loaded, default to .python_history,
# or PYTHON_HISTORY.
# The guard is necessary to avoid doubling history size at
# each interpreter exit when readline was already configured
# through a PYTHONSTARTUP hook, see:
# http://bugs.python.org/issue5845#msg198636
history = gethistoryfile()
if os.getenv("PYTHON_BASIC_REPL") or not CAN_USE_PYREPL:
readline_module = readline
else:

if CAN_USE_PYREPL:
readline_module = _pyrepl.readline
exceptions = (OSError, *_pyrepl.unix_console._error)
else:
readline_module = readline
exceptions = OSError

try:
readline_module.read_history_file(history)
except (OSError,* _pyrepl.unix_console._error):
except exceptions:
pass

def write_history():
Expand Down
12 changes: 12 additions & 0 deletions Lib/test/test_pyrepl/test_pyrepl.py
Original file line number Diff line number Diff line change
Expand Up @@ -1204,6 +1204,18 @@ def test_python_basic_repl(self):
self.assertNotIn("Exception", output)
self.assertNotIn("Traceback", output)

# The site module must not load _pyrepl if PYTHON_BASIC_REPL is set
commands = ("import sys\n"
"print('_pyrepl' in sys.modules)\n"
"exit()\n")
env["PYTHON_BASIC_REPL"] = "1"
output, exit_code = self.run_repl(commands, env=env)
self.assertEqual(exit_code, 0)
self.assertIn("False", output)
self.assertNotIn("True", output)
self.assertNotIn("Exception", output)
self.assertNotIn("Traceback", output)

@force_not_colorized
def test_bad_sys_excepthook_doesnt_crash_pyrepl(self):
env = os.environ.copy()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
If the :envvar:`PYTHON_BASIC_REPL` environment variable is set, the
:mod:`site` module no longer imports the :mod:`!_pyrepl` module. Moreover,
the :mod:`site` module now respects :option:`-E` and :option:`-I` command
line options: ignore :envvar:`PYTHON_BASIC_REPL` in this case. Patch by
Victor Stinner.

0 comments on commit 65ce228

Please sign in to comment.