gh-122273: Support PyREPL history on Windows (#127141)

Co-authored-by: devdanzin <74280297+devdanzin@users.noreply.github.com>
This commit is contained in:
Victor Stinner 2024-11-26 10:21:57 +01:00 committed by GitHub
parent f46d847574
commit 3c7a90a831
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 40 additions and 20 deletions

View file

@ -450,7 +450,9 @@ class _ReadlineWrapper:
def write_history_file(self, filename: str = gethistoryfile()) -> None: def write_history_file(self, filename: str = gethistoryfile()) -> None:
maxlength = self.saved_history_length maxlength = self.saved_history_length
history = self.get_reader().get_trimmed_history(maxlength) history = self.get_reader().get_trimmed_history(maxlength)
with open(os.path.expanduser(filename), "w", encoding="utf-8") as f: f = open(os.path.expanduser(filename), "w",
encoding="utf-8", newline="\n")
with f:
for entry in history: for entry in history:
entry = entry.replace("\n", "\r\n") # multiline history support entry = entry.replace("\n", "\r\n") # multiline history support
f.write(entry + "\n") f.write(entry + "\n")

View file

@ -498,9 +498,18 @@ def register_readline():
PYTHON_BASIC_REPL = False PYTHON_BASIC_REPL = False
import atexit import atexit
try:
try: try:
import readline import readline
except ImportError:
readline = None
else:
import rlcompleter # noqa: F401 import rlcompleter # noqa: F401
except ImportError:
return
try:
if PYTHON_BASIC_REPL: if PYTHON_BASIC_REPL:
CAN_USE_PYREPL = False CAN_USE_PYREPL = False
else: else:
@ -508,13 +517,19 @@ def register_readline():
sys.path = [p for p in original_path if p != ''] sys.path = [p for p in original_path if p != '']
try: try:
import _pyrepl.readline import _pyrepl.readline
if os.name == "nt":
import _pyrepl.windows_console
console_errors = (_pyrepl.windows_console._error,)
else:
import _pyrepl.unix_console import _pyrepl.unix_console
console_errors = _pyrepl.unix_console._error
from _pyrepl.main import CAN_USE_PYREPL from _pyrepl.main import CAN_USE_PYREPL
finally: finally:
sys.path = original_path sys.path = original_path
except ImportError: except ImportError:
return return
if readline is not None:
# Reading the initialization (config) file may not be enough to set a # Reading the initialization (config) file may not be enough to set a
# completion key, so we set one first and then read the file. # completion key, so we set one first and then read the file.
if readline.backend == 'editline': if readline.backend == 'editline':
@ -531,7 +546,7 @@ def register_readline():
# want to ignore the exception. # want to ignore the exception.
pass pass
if readline.get_current_history_length() == 0: if readline is None or readline.get_current_history_length() == 0:
# If no history was loaded, default to .python_history, # If no history was loaded, default to .python_history,
# or PYTHON_HISTORY. # or PYTHON_HISTORY.
# The guard is necessary to avoid doubling history size at # The guard is necessary to avoid doubling history size at
@ -542,8 +557,10 @@ def register_readline():
if CAN_USE_PYREPL: if CAN_USE_PYREPL:
readline_module = _pyrepl.readline readline_module = _pyrepl.readline
exceptions = (OSError, *_pyrepl.unix_console._error) exceptions = (OSError, *console_errors)
else: else:
if readline is None:
return
readline_module = readline readline_module = readline
exceptions = OSError exceptions = OSError

View file

@ -0,0 +1 @@
Support PyREPL history on Windows. Patch by devdanzin and Victor Stinner.