Closed
Description
Bug report
Bug description:
Since the libedit transition (correction: If an end user switches from a GNU readline build of Python to an editline build of Python), several important functions related to history files are broken.
- It is inconvenient enough that history files written by GNU readline based
readline
module are unreadable and result in a rather confusingOSError
withexc.errno == errno.EINVAL
(without a corresponding operating system routine that returns such an error), but a workaround intercepting thisOSError
can be written that converts the old format to the new one. This has been covered before, e.g. in The New REPL Does Not Load My Command History #120766. - More importantly, history files written by libedit based
readline
module are unreadable by itself whenset_history_length
is used, as demonstrated by the code below. - While a workaround for that is also possible (also below), as far as I can tell, until 3.13, so until a year from now (?) (whenever Add
readline.backend
for the backendreadline
uses #112510 becomes available in a release), your only option is"libedit" in readline.__doc__
, which I expect will be what many people will leave in the codebase even oncereadline.backend
becomes available.
Reproducer:
import readline
readline.add_history("foo bar")
readline.add_history("nope nope")
readline.write_history_file("history-works")
# this works:
readline.read_history_file("history-works")
readline.set_history_length(2)
readline.write_history_file("history-breaks")
# this breaks:
readline.read_history_file("history-breaks")
Workaround:
def _is_using_libedit():
if hasattr(readline, "backend"):
return readline.backend == "editline"
else:
return "libedit" in readline.__doc__
readline.set_history_length(1000)
if _is_using_libedit():
readline.replace_history_item(
max(0, readline.get_current_history_length() - readline.get_history_length()),
"_HiStOrY_V2_")
CPython versions tested on:
3.12
Operating systems tested on:
Linux
Linked PRs
- gh-121160: Add a test for readline.set_history_length #121326
- gh-121160: Note that readline libraries using different history formats. #121327
- [3.13] gh-121160: Add some tests for readline.set_history_length (GH-121326) #121856
- [3.12] gh-121160: Add some tests for readline.set_history_length (GH-121326) #121857
- [3.13] gh-121160: Note that readline libraries using different history formats. (GH-121327) #122030
- [3.12] gh-121160: Note that readline libraries using different history formats. (GH-121327) #122031