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
readlinemodule are unreadable and result in a rather confusingOSErrorwithexc.errno == errno.EINVAL(without a corresponding operating system routine that returns such an error), but a workaround intercepting thisOSErrorcan 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
readlinemodule are unreadable by itself whenset_history_lengthis 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.backendfor the backendreadlineuses #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.backendbecomes 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