Skip to content

Commit 8195067

Browse files
committed
Refactor site.register_readline()
* make readline stuff more symmetrical wrt reading/writing * prevent truncation of the history file * add regression test Should finally address python#121245.
1 parent 7a807c3 commit 8195067

File tree

2 files changed

+31
-14
lines changed

2 files changed

+31
-14
lines changed

Lib/site.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -509,35 +509,35 @@ def register_readline():
509509
pass
510510

511511
if readline.get_current_history_length() == 0:
512+
try:
513+
from _pyrepl.main import CAN_USE_PYREPL
514+
except ImportError:
515+
CAN_USE_PYREPL = False
512516
# If no history was loaded, default to .python_history,
513517
# or PYTHON_HISTORY.
514518
# The guard is necessary to avoid doubling history size at
515519
# each interpreter exit when readline was already configured
516520
# through a PYTHONSTARTUP hook, see:
517521
# http://bugs.python.org/issue5845#msg198636
518522
history = gethistoryfile()
523+
if os.getenv("PYTHON_BASIC_REPL") or not CAN_USE_PYREPL:
524+
my_readline = readline
525+
else:
526+
my_readline = _pyrepl.readline
519527
try:
520-
if os.getenv("PYTHON_BASIC_REPL"):
521-
readline.read_history_file(history)
522-
else:
523-
_pyrepl.readline.read_history_file(history)
528+
my_readline.read_history_file(history)
524529
except (OSError,* _pyrepl.unix_console._error):
525530
pass
526531

527532
def write_history():
528533
try:
529-
from _pyrepl.main import CAN_USE_PYREPL
530-
except ImportError:
531-
CAN_USE_PYREPL = False
532-
533-
try:
534-
if os.getenv("PYTHON_BASIC_REPL") or not CAN_USE_PYREPL:
535-
readline.write_history_file(history)
536-
else:
537-
_pyrepl.readline.write_history_file(history)
538-
except (FileNotFoundError, PermissionError):
534+
if my_readline.get_current_history_length() > 0:
535+
my_readline.write_history_file(history)
536+
except (FileNotFoundError, PermissionError,
537+
_pyrepl.unix_console.InvalidTerminal):
539538
# home directory does not exist or is not writable
540539
# https://bugs.python.org/issue19891
540+
# or terminal doesn't have the required capability
541541
pass
542542

543543
atexit.register(write_history)

Lib/test/test_pyrepl/test_pyrepl.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import io
22
import itertools
33
import os
4+
import pathlib
45
import rlcompleter
56
import select
67
import subprocess
78
import sys
9+
import tempfile
810
from unittest import TestCase, skipUnless
911
from unittest.mock import patch
1012
from test.support import force_not_colorized
@@ -898,6 +900,21 @@ def test_python_basic_repl(self):
898900
self.assertNotIn("Exception", output)
899901
self.assertNotIn("Traceback", output)
900902

903+
def setUp(self):
904+
self.hfile = tempfile.NamedTemporaryFile(delete=False)
905+
906+
def tearDown(self):
907+
self.hfile.close()
908+
909+
def test_not_wiping_history_file(self):
910+
env = os.environ.copy()
911+
env.update({"PYTHON_HISTORY": self.hfile.name})
912+
commands = "123\nspam\nexit()\n"
913+
output, exit_code = self.run_repl(commands, env=env)
914+
self.assertIn("123", output)
915+
self.assertIn("spam", output)
916+
self.assertNotEqual(pathlib.Path(self.hfile.name).stat().st_size, 0)
917+
901918
def run_repl(self, repl_input: str | list[str], env: dict | None = None) -> tuple[str, int]:
902919
master_fd, slave_fd = pty.openpty()
903920
process = subprocess.Popen(

0 commit comments

Comments
 (0)