Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

max_help_position is not works in argparse library #69484

Closed
morden2k mannequin opened this issue Oct 2, 2015 · 6 comments
Closed

max_help_position is not works in argparse library #69484

morden2k mannequin opened this issue Oct 2, 2015 · 6 comments
Labels
stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error

Comments

@morden2k
Copy link
Mannequin

morden2k mannequin commented Oct 2, 2015

BPO 25297
Files
  • issue25297.py
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = None
    created_at = <Date 2015-10-02.08:55:13.943>
    labels = ['library']
    title = 'max_help_position is not works in argparse library'
    updated_at = <Date 2015-10-03.21:30:55.770>
    user = 'https://bugs.python.org/morden2k'

    bugs.python.org fields:

    activity = <Date 2015-10-03.21:30:55.770>
    actor = 'paul.j3'
    assignee = 'none'
    closed = False
    closed_date = None
    closer = None
    components = ['Library (Lib)']
    creation = <Date 2015-10-02.08:55:13.943>
    creator = 'morden2k'
    dependencies = []
    files = ['40661']
    hgrepos = []
    issue_num = 25297
    keywords = []
    message_count = 5.0
    messages = ['252093', '252095', '252144', '252164', '252242']
    nosy_count = 2.0
    nosy_names = ['paul.j3', 'morden2k']
    pr_nums = []
    priority = 'normal'
    resolution = None
    stage = None
    status = 'open'
    superseder = None
    type = None
    url = 'https://bugs.python.org/issue25297'
    versions = ['Python 2.7']

    @morden2k
    Copy link
    Mannequin Author

    morden2k mannequin commented Oct 2, 2015

    Hi colleagues I have the code (max_help_position is 2000):

    formatter_class=lambda prog: argparse.HelpFormatter(prog, max_help_position=2000)
    parser = argparse.ArgumentParser(formatter_class=formatter_class)
    
    
    subparsers = parser.add_subparsers(title="Commands", metavar="<command>")
    
    cmd_parser = subparsers.add_parser('long_long_long_long_long_long_long',
                                       help='- jksljdalkjda',
                                       formatter_class=formatter_class)
    
    args = parser.parse_args(['-h'])
    print args

    Result:

    we have

    optional arguments:
      -h, --help                          show this help message and exit
    
    Commands:
      <command>
        long_long_long_long_long_long_long
                                          - jksljdalkjda
        small                             - descr
    

    instead

    optional arguments:
      -h, --help  show this help message and exit
    
    Commands:
      <command>
        long_long_long_long_long_long_long - jksljdalkjda
        small                              - descr
    

    The code:

    class MyFormatter(argparse.HelpFormatter):
        def __init__(self, prog):
            super(MyFormatter, self).__init__(prog, max_help_position=2000, width=2000)
            self._max_help_position = 2000
            self._action_max_length += 4

    got same result.

    The strings like:

    formatter_class = lambda prog: argparse.HelpFormatter(prog,
                      max_help_position=2000, width=2000)
    
    formatter_class = lambda prog: argparse.HelpFormatter(prog,
                      max_help_position=1000, width=2000)
    
    formatter_class = lambda prog: argparse.HelpFormatter(prog,
                      max_help_position=2000, width=1000)

    got same result: we always have new line after command.

    @morden2k morden2k mannequin added the stdlib Python modules in the Lib dir label Oct 2, 2015
    @morden2k
    Copy link
    Mannequin Author

    morden2k mannequin commented Oct 2, 2015

    Problem also described on http://stackoverflow.com/questions/32888815/

    @paulj3
    Copy link
    Mannequin

    paulj3 mannequin commented Oct 2, 2015

    My testing shows that it's a problem with the subparsers listing. When regular arguments are long, 'max_help_position' works (within limits allowed by 'width').

    @paulj3
    Copy link
    Mannequin

    paulj3 mannequin commented Oct 2, 2015

    There's a bug in the HelpFormatter.add_argument method. It does not take into account the extra indentation of subactions (sub parsers) when calculating self._action_max_length.

    The corrected method and a test case is in the attached file.

    class MyFormatter(argparse.HelpFormatter):
        """
        Corrected _max_action_length for the indenting of subactions
        """
        def add_argument(self, action):
            if action.help is not argparse.SUPPRESS:
    
                # find all invocations
                get_invocation = self._format_action_invocation
                invocations = [get_invocation(action)]
                current_indent = self._current_indent
                for subaction in self._iter_indented_subactions(action):
                    # compensate for the indent that will be added
                    indent_chg = self._current_indent - current_indent
                    added_indent = 'x'*indent_chg
                    invocations.append(added_indent + get_invocation( subaction) )
                # print('inv', invocations)
    
                # update the maximum item length
                invocation_length = max([len(s) for s in invocations])
                action_length = invocation_length + self._current_indent
                self._action_max_length = max(self._action_max_length,
                                              action_length)
    
                # add the item to the list
                self._add_item(self._format_action, [action])

    Without this correction self._action_max_length is off by 2 if a subparser has the longest invocation. Normally that wouldn't be an issue since normally subparser names are short and easy to use. But with the 'aliases' that newer argparse allows, the invocation could be longer, and possibly longer than regular arguments.

    I haven't passed this correction through test_argparse.py. It also would need a test case or two. I don't think it need a documentation change.

    I don't know if this correction will work with the subparser grouping proposed in http://bugs.python.org/issue9341.

    @paulj3
    Copy link
    Mannequin

    paulj3 mannequin commented Oct 3, 2015

    The unittest test_argparse.py has one related test

    class TestAddSubparsers
    def test_alias_help

    has a long enough subparser invocation (with aliases) to produce wrapping with the default 24 max position:

            commands:
              COMMAND
                1 (1alias1, 1alias2)
                                    1 help
                2                   2 help
    

    I don't see anything in the test file that tries to vary the max_help_position parameter.

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    @terryjreedy terryjreedy added the type-bug An unexpected behavior, bug, or error label Aug 16, 2023
    @serhiy-storchaka
    Copy link
    Member

    Fixed by #124230.

    @serhiy-storchaka serhiy-storchaka closed this as not planned Won't fix, can't repro, duplicate, stale Sep 25, 2024
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error
    Projects
    Status: Doc issues
    Development

    No branches or pull requests

    2 participants