https://github.com/python/cpython/commit/3c7a90a83146dc6e55f6f9ecd9af0bf9682f98a6
commit: 3c7a90a83146dc6e55f6f9ecd9af0bf9682f98a6
branch: main
author: Victor Stinner <[email protected]>
committer: vstinner <[email protected]>
date: 2024-11-26T10:21:57+01:00
summary:

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

Co-authored-by: devdanzin <[email protected]>

files:
A Misc/NEWS.d/next/Library/2024-11-22-09-23-41.gh-issue-122273.H8M6fd.rst
M Lib/_pyrepl/readline.py
M Lib/site.py

diff --git a/Lib/_pyrepl/readline.py b/Lib/_pyrepl/readline.py
index 5e1d3085874380..888185eb03be66 100644
--- a/Lib/_pyrepl/readline.py
+++ b/Lib/_pyrepl/readline.py
@@ -450,7 +450,9 @@ def read_history_file(self, filename: str = 
gethistoryfile()) -> None:
     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 54f07ab5b4e6d5..abf4b520244554 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 00000000000000..99071e05377e33
--- /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.

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]

Reply via email to