Skip to content
Closed
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Lib/_pyrepl/readline.py
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ 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:
with open(os.path.expanduser(filename), "w", encoding="utf-8", newline="\n") as f:
for entry in history:
entry = entry.replace("\n", "\r\n") # multiline history support
f.write(entry + "\n")
Expand Down
23 changes: 17 additions & 6 deletions Lib/site.py
Original file line number Diff line number Diff line change
Expand Up @@ -498,26 +498,37 @@ def register_readline():

import atexit
try:
import readline
try:
import readline
real_readline = True
except ImportError:
import _pyrepl.readline as readline
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should not import if PYTHON_BASIC_REPL is set.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part replaces an unconditional import of readline:

 import atexit
     try:
-        import readline
+        try:
+            import readline
+            real_readline = True
+        except ImportError:
+            import _pyrepl.readline as readline
+            real_readline = False
         import rlcompleter  # noqa: F401

Then readline is used in a couple places without checking it's a valid module. Should I set readline = None for the PYTHON_BASIC_REPL case and check against it being falsy where needed?

Should look something like:

diff --git a/Lib/site.py b/Lib/site.py
index 9d3352c70e3..a27373000fa 100644
--- a/Lib/site.py
+++ b/Lib/site.py
@@ -502,12 +502,13 @@ def register_readline():
             import readline
             real_readline = True
         except ImportError:
-            import _pyrepl.readline as readline
+            readline = None
             real_readline = False
         import rlcompleter  # noqa: F401
         if PYTHON_BASIC_REPL:
             CAN_USE_PYREPL = False
         else:
+            import _pyrepl.readline as readline
             from _pyrepl.main import CAN_USE_PYREPL
             if real_readline:
                 import _pyrepl.unix_console
@@ -521,9 +522,10 @@ def register_readline():
 
     # 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 getattr(readline, "backend", None) == 'editline':
+    backend = getattr(readline, "backend", None)
+    if backend == 'editline':
         readline.parse_and_bind('bind ^I rl_complete')
-    else:
+    elif backend:
         readline.parse_and_bind('tab: complete')
 
     try:
@@ -536,7 +538,7 @@ def register_readline():
         # want to ignore the exception.
         pass
 
-    if readline.get_current_history_length() == 0:
+    if readline and 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
@@ -553,13 +555,15 @@ def register_readline():
             exceptions = OSError
 
         try:
-            readline_module.read_history_file(history)
+            if readline:
+                readline_module.read_history_file(history)
         except exceptions:
             pass
 
         def write_history():
             try:
-                readline_module.write_history_file(history)
+                if readline:
+                    readline_module.write_history_file(history)
             except (FileNotFoundError, PermissionError):
                 # home directory does not exist or is not writable
                 # https://bugs.python.org/issue19891

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've committed a version of the approach above.

real_readline = False
import rlcompleter # noqa: F401
if PYTHON_BASIC_REPL:
CAN_USE_PYREPL = False
else:
import _pyrepl.readline
import _pyrepl.unix_console
from _pyrepl.main import CAN_USE_PYREPL
if real_readline:
import _pyrepl.unix_console
console_error = _pyrepl.unix_console._error
else:
import _pyrepl.windows_console
console_error = [_pyrepl.windows_console._error]

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':
if hasattr(readline, "backend") and readline.backend == 'editline':
readline.parse_and_bind('bind ^I rl_complete')
else:
readline.parse_and_bind('tab: complete')

try:
readline.read_init_file()
if real_readline:
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
Expand All @@ -536,7 +547,7 @@ def register_readline():

if CAN_USE_PYREPL:
readline_module = _pyrepl.readline
exceptions = (OSError, *_pyrepl.unix_console._error)
exceptions = (OSError, *console_error)
else:
readline_module = readline
exceptions = OSError
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add support for command history in the new REPL running on Windows.
Loading