Skip to content

readline.set_history_length corrupts history files when used in a libedit build #121160

Closed

Description

@whitequark

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.

  1. It is inconvenient enough that history files written by GNU readline based readline module are unreadable and result in a rather confusing OSError with exc.errno == errno.EINVAL (without a corresponding operating system routine that returns such an error), but a workaround intercepting this OSError 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.
  2. More importantly, history files written by libedit based readline module are unreadable by itself when set_history_length is used, as demonstrated by the code below.
  3. 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 backend readline 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 once readline.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

Activity

  1. added 2 commits that reference this issue on Jul 16, 2024
  2. added 2 commits that reference this issue on Jul 16, 2024
  3. added a commit that references this issue on Jul 17, 2024
  4. encukou commented on Jul 18, 2024

    @encukou
    Member

    Reported to python-build-standalone: astral-sh/python-build-standalone#281

  5. added a commit that references this issue on Jul 19, 2024
  6. added a commit that references this issue on Jul 19, 2024
  7. added 3 commits that reference this issue on Jul 19, 2024
  8. encukou commented on Jul 19, 2024

    @encukou
    Member

    This is about as much as we can do on the CPython side. If anyone has more ideas, let's reopen.

  9. whitequark commented on Jul 19, 2024

    @whitequark
    Author

    Thanks again for handling this! It wasn't my proposed solution but as a maintainer I recognize that mine wasn't really viable for CPython.

  10. gpshead commented on Sep 8, 2026

    @gpshead
    Member

    FWIW I'm tackling this with a libedit specific workaround in #157165 for effective duplicate issue #123018. yes it is gross to carry a workaround. but it is practical. getting NetBSD libedit to adopt a fix and getting that plumbed through to the various other versions of it is frankly not likely to happen in any meaningfully timely manner is unlikely.

  11. encukou commented on Sep 8, 2026

    @encukou
    Member

    Yeah, carrying a 200-line workaround for an unsupported system still feels inappropriate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    topic-replRelated to the interactive shelltype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions