From 3c7a90a83146dc6e55f6f9ecd9af0bf9682f98a6 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 26 Nov 2024 10:21:57 +0100 Subject: gh-122273: Support PyREPL history on Windows (#127141) Co-authored-by: devdanzin <74280297+devdanzin@users.noreply.github.com> --- Lib/_pyrepl/readline.py | 4 +- Lib/site.py | 55 ++++++++++++++-------- .../2024-11-22-09-23-41.gh-issue-122273.H8M6fd.rst | 1 + 3 files changed, 40 insertions(+), 20 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-11-22-09-23-41.gh-issue-122273.H8M6fd.rst diff --git a/Lib/_pyrepl/readline.py b/Lib/_pyrepl/readline.py index 5e1d308..888185e 100644 --- a/Lib/_pyrepl/readline.py +++ b/Lib/_pyrepl/readline.py @@ -450,7 +450,9 @@ class _ReadlineWrapper: def write_history_file(self, filename: str = gethistoryfile()) -> None: maxlength = self.saved_history_length 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: entry = entry.replace("\n", "\r\n") # multiline history support f.write(entry + "\n") diff --git a/Lib/site.py b/Lib/site.py index 54f07ab..abf4b52 100644 --- a/Lib/site.py +++ b/Lib/site.py @@ -498,9 +498,18 @@ def register_readline(): PYTHON_BASIC_REPL = False import atexit + + try: + try: + import readline + except ImportError: + readline = None + else: + import rlcompleter # noqa: F401 + except ImportError: + return + try: - import readline - import rlcompleter # noqa: F401 if PYTHON_BASIC_REPL: CAN_USE_PYREPL = False else: @@ -508,30 +517,36 @@ def register_readline(): sys.path = [p for p in original_path if p != ''] try: import _pyrepl.readline - import _pyrepl.unix_console + if os.name == "nt": + import _pyrepl.windows_console + console_errors = (_pyrepl.windows_console._error,) + else: + import _pyrepl.unix_console + console_errors = _pyrepl.unix_console._error from _pyrepl.main import CAN_USE_PYREPL finally: sys.path = original_path except ImportError: return - # Reading the initialization (config) file may not be enough to set a - # completion key, so we set one first and then read the file. - if readline.backend == 'editline': - readline.parse_and_bind('bind ^I rl_complete') - else: - readline.parse_and_bind('tab: complete') + if readline is not None: + # Reading the initialization (config) file may not be enough to set a + # completion key, so we set one first and then read the file. + if readline.backend == 'editline': + readline.parse_and_bind('bind ^I rl_complete') + else: + readline.parse_and_bind('tab: complete') - try: - readline.read_init_file() - except OSError: - # An OSError here could have many causes, but the most likely one - # is that there's no .inputrc file (or .editrc file in the case of - # Mac OS X + libedit) in the expected location. In that case, we - # want to ignore the exception. - pass + try: + readline.read_init_file() + except OSError: + # An OSError here could have many causes, but the most likely one + # is that there's no .inputrc file (or .editrc file in the case of + # Mac OS X + libedit) in the expected location. In that case, we + # want to ignore the exception. + 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, # or PYTHON_HISTORY. # The guard is necessary to avoid doubling history size at @@ -542,8 +557,10 @@ def register_readline(): if CAN_USE_PYREPL: readline_module = _pyrepl.readline - exceptions = (OSError, *_pyrepl.unix_console._error) + exceptions = (OSError, *console_errors) else: + if readline is None: + return readline_module = readline exceptions = OSError diff --git a/Misc/NEWS.d/next/Library/2024-11-22-09-23-41.gh-issue-122273.H8M6fd.rst b/Misc/NEWS.d/next/Library/2024-11-22-09-23-41.gh-issue-122273.H8M6fd.rst new file mode 100644 index 0000000..99071e0 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-11-22-09-23-41.gh-issue-122273.H8M6fd.rst @@ -0,0 +1 @@ +Support PyREPL history on Windows. Patch by devdanzin and Victor Stinner. -- cgit v0.12