Skip to content

Commit

Permalink
support.arepl: upgrade GNU readline history files to libedit format.
Browse files Browse the repository at this point in the history
Previously this would cause a crash with an opaque EINVAL OSError that
doesn't come from a syscall.

Related to python/cpython#102130.
  • Loading branch information
whitequark committed Jun 29, 2024
1 parent 4d38479 commit 271f64b
Showing 1 changed file with 25 additions and 0 deletions.
25 changes: 25 additions & 0 deletions software/glasgow/support/arepl.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import os
import sys
import ast
import errno
import codeop
import signal
import logging
import asyncio
import builtins
import traceback
Expand All @@ -15,6 +17,9 @@
from .asignal import wait_for_signal


logger = logging.getLogger(__loader__.name)


class AsyncInteractiveConsole:
def __init__(self, locals, *, run_callback=None):
self.locals = {"__name__": "__console__", "sleep": asyncio.sleep, **locals}
Expand All @@ -31,6 +36,26 @@ def _init_readline(self):
self._history_filename = os.path.expanduser("~/.glasgow-history")
try:
readline.read_history_file(self._history_filename)
except OSError as exc:
if exc.errno == errno.EINVAL: # (screaming internally)
assert "libedit" in readline.__doc__ # (AAAAAAAA)
with open(self._history_filename, "r") as f:
history = f.readlines()
assert history[:1] != ["_HiStOrY_V2_"], "History file already converted"
backup_filename = f"{self._history_filename}.gnu"
with open(backup_filename, "w") as f:
f.writelines(history)
new_filename = f"{self._history_filename}.new"
with open(f"{self._history_filename}.new", "w") as f:
f.write("_HiStOrY_V2_\n")
f.writelines([line.replace(" ", r"\040") for line in history])
os.rename(new_filename, self._history_filename)
logger.warning(f"this Python distribution uses libedit instead of GNU readline, "
f"and their history file formats are not compatible")
logger.warning(f"REPL history file has been converted from the GNU readline format "
f"to the libedit format; backup saved to {backup_filename}")
# meow, why can't libedit do this itself ;_; am sad cat
readline.read_history_file(self._history_filename)
except FileNotFoundError:
pass

Expand Down

0 comments on commit 271f64b

Please sign in to comment.