GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — argparse.HelpFormatter subclasses may be broken by 3.14 changes · Issue #133653 · python/cpython

argparse.HelpFormatter subclasses may be broken by 3.14 changes #133653

New issue
Copy link
New issue
Copy link
Closed
Closed
argparse.HelpFormatter subclasses may be broken by 3.14 changes#133653
Copy link
Assignees
serhiy-storchaka
Labels
3.14bugs and security fixesbugs and security fixesstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

Description

@iritkatriel
iritkatriel
opened on May 8, 2025
Issue body actions

I came across this trying to run mypy benchmarks. The version I had contained

class AugmentedHelpFormatter(argparse.RawDescriptionHelpFormatter):
    def __init__(self, prog: str) -> None:
        super().__init__(prog=prog, max_help_position=30)

Which was rewritten in a newer version to:

class AugmentedHelpFormatter(argparse.RawDescriptionHelpFormatter):
    def __init__(self, prog: str, **kwargs: Any) -> None:
        super().__init__(prog=prog, max_help_position=30, **kwargs)

The changes in #124456 and #132323 can be made without breaking user code, if they accept the new args as **kwargs, extract their values from kwargs if they are there, and continue working as before if not. Is there a good reason not to do this?

Do these changes currently comply with Python's backwards compatibility policy?

Linked PRs

  • gh-133653: Fix subclassing HelpFormatter #133668
  • gh-133653: Fix argparse.ArgumentParser with the formatter_class argument #133813
  • [3.14] gh-133653: Fix argparse.ArgumentParser with the formatter_class argument (GH-133813) #133941

Activity

  1. iritkatriel
    added
    type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
    stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory
    3.14bugs and security fixesbugs and security fixes
    on May 8, 2025
  2. iritkatriel commented on May 8, 2025

    @iritkatriel
    iritkatriel
    on May 8, 2025
    MemberAuthor
    More actions

    CC @hugovk @savannahostrowski .

  3. hugovk commented on May 8, 2025

    @hugovk
    hugovk
    on May 8, 2025
    Member
    More actions

    The changes in #124456 and #132323 can be made without breaking user code, if they accept the new args as **kwargs, extract their values from kwargs if they are there, and continue working as before if not. Is there a good reason not to do this?

    Let's do this.

    Would you like to open a PR? I'm also happy to do it.

  4. iritkatriel commented on May 8, 2025

    @iritkatriel
    iritkatriel
    on May 8, 2025
    MemberAuthor
    More actions

    Please go ahead.

    Reacted by Hugo van Kemenade
  5. iritkatriel commented on May 8, 2025

    @iritkatriel
    iritkatriel
    on May 8, 2025
    MemberAuthor
    More actions

    Something like

            prefix_chars = kwargs.get('prefix_chars', '-')
            color = kwargs.get('color', False)
    Reacted by Hugo van Kemenade
  6. The-Compiler commented on May 8, 2025

    @The-Compiler
    The-Compiler
    on May 8, 2025
    Contributor
    More actions

    Do these changes currently comply with Python's backwards compatibility policy?

    FWIW, argparse.HelpFormatter itself is undocumented and the docstrings say:

    cpython/Lib/argparse.py

    Lines 62 to 64 in 0ec8fc8

    (Also note that HelpFormatter and RawDescriptionHelpFormatter are only
    considered public as object names -- the API of the formatter objects is
    still considered an implementation detail.)

    cpython/Lib/argparse.py

    Lines 157 to 162 in 0ec8fc8

    class HelpFormatter(object):
    """Formatter for generating usage messages and argument help strings.
    Only the name of this class is considered a public API. All the methods
    provided by the class are considered an implementation detail.
    """

    But despite that, subclassing argparse.HelpFormatter seems to be a common occurrence, and many implementations seem to not use **kwargs.

    Reacted by Hugo van Kemenade and Edgar Ramírez Mondragón
  7. hugovk commented on May 8, 2025

    @hugovk
    hugovk
    on May 8, 2025
    Member
    More actions

    How does PR #133668 look?

  8. serhiy-storchaka commented on May 8, 2025

    @serhiy-storchaka
    serhiy-storchaka
    on May 8, 2025
    Member
    More actions

    I think this is a documentation issue. The only way to fix it reliably is to properly document the HelpFormatter class and how it cab be extended.

    Currently the HelpFormatter class is not documented. It's subclassing is not officially supported. You need to look in the source code to find about max_help_position.

    Reacted by Edgar Ramírez Mondragón
  9. iritkatriel commented on May 9, 2025

    @iritkatriel
    iritkatriel
    on May 9, 2025
    MemberAuthor
    More actions

    The only way to fix it reliably is to properly document the HelpFormatter class and how it cab be extended.

    As discussed on the PR - doc change is welcome but it is not the only way to fix this.

    I think we should add a setter method for the new fields so that the signature of __init__ doesn't need to change.

    We saw two libraries break already, there will be more post release. There is no point repeatedly litigating this with users over the next 3-5 years if we can avoid that with a simple change now.

  10. serhiy-storchaka commented on May 9, 2025

    @serhiy-storchaka
    serhiy-storchaka
    on May 9, 2025
    Member
    More actions

    There is something similar issue #133745. It is more serious, because the documented contract was changed. For HelpFormatter there is no documented contract. We can apply solution similar to the code that was used before #128308 -- pass only prog to the factory, and set other parameters as private HelpFormatter attributes. This approach has many drawbacks. It still can break custom formatters, and for some users it will only defer breakage fr future versions. In long run, it is better to break the user code now. But we need the documentation to make sure that users will write correct code which will not break in future.

  11. iritkatriel commented on May 9, 2025

    @iritkatriel
    iritkatriel
    on May 9, 2025
    MemberAuthor
    More actions

    Ultimately it's up to the 3.14 release manager.

  12. serhiy-storchaka
    self-assigned this
    on May 10, 2025
  13. serhiy-storchaka commented on May 10, 2025

    @serhiy-storchaka
    serhiy-storchaka
    on May 10, 2025
    Member
    More actions

    Well, I have a plan to make the transition smoother, and I'm working on it.

  14. serhiy-storchaka
    added a commit that references this issue on May 10, 2025

    pythongh-133653: Fix argparse.ArgumentParser with the formatter_class…

    ef5d142
  15. serhiy-storchaka commented on May 10, 2025

    @serhiy-storchaka
    serhiy-storchaka
    on May 10, 2025
    Member
    More actions

    There were other issues. Colorizing did not work when formatter_class is a function. And all failed when prefix_chars is not standard and formatter_class is a function, even without colorizing.

  16. gentoo-bot
    added a commit that references this issue on May 11, 2025

    dev-python/pygments: enable py3.14

    92d1c6b
  17. tanuki-no
    added a commit that references this issue on May 12, 2025

    dev-python/pygments: enable py3.14

    b73bf53
  18. serhiy-storchaka
    added a commit that references this issue on May 12, 2025

    gh-133653: Fix argparse.ArgumentParser with the formatter_class argum…

    734e15b
  19. miss-islington
    added a commit that references this issue on May 12, 2025

    pythongh-133653: Fix argparse.ArgumentParser with the formatter_class…

    74c8bce
  20. serhiy-storchaka
    closed this as completedon May 12, 2025
  21. serhiy-storchaka commented on May 12, 2025

    @serhiy-storchaka
    serhiy-storchaka
    on May 12, 2025
    Member
    More actions

    I think we should add a setter method for the new fields so that the signature of __init__ doesn't need to change.

    I implemented this solution. Also, for now, there is no need to pass prefix_chars.

    Reacted by Hugo van Kemenade
  22. serhiy-storchaka
    added a commit that references this issue on May 12, 2025

    [3.14] gh-133653: Fix argparse.ArgumentParser with the formatter_clas…

    c15980b
  23. Pranjal095
    added a commit that references this issue on Jul 12, 2025

    pythongh-133653: Fix argparse.ArgumentParser with the formatter_class…

    b966a9e
  24. taegyunkim
    added a commit that references this issue on Aug 4, 2025

    pythongh-133653: Fix argparse.ArgumentParser with the formatter_class…

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

Metadata

Metadata

Assignees

  • @serhiy-storchaka
    serhiy-storchaka

Labels

3.14bugs and security fixesbugs and security fixesstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    You are visitor 01402503 — GeezerVison does not store the pages you look up.
    Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.