Max_help_position Is Not Works In Python Argparse Library

You need to increase the width as well

try:

formatter_class=lambda prog: argparse.HelpFormatter(prog, max_help_position=100, width=200)

As my earlier thoughts (below) show, the formatting considers overall width as well as the max_position value.

(earlier)

In my limited testing, your formatter subclass seems to work. But I haven't pushed the limits.

You many need to dig more into the Formatter code.

For example there is a format_action method that actually uses the max_width

def _format_action(self, action): # determine the required width and the entry label help_position = min(self._action_max_length + 2, self._max_help_position) help_width = self._width - help_position action_width = help_position - self._current_indent - 2 ...

Notice that it interacts with the width. Then it goes on to actually format the help lines and perform wrapping. So the actual implementation is not simple.

I'm not following your question about spaces. format_help commands the formatter to format a number of sections (including argument groups). The sections (usually) end with a couple of line feeds. Upon assembling them the formatter removes 'unnecessary' line feeds, leaving one space between groups. The subparser doesn't fit other categories, so I'd have to study the code to see exactly how it is handled.

Your lambda definition works as well. I haven't seen it before, and I don't think it's what the developers intended, but Python that doesn't matter - if it works.

Playing around with values and strings, I see that max_position up to about 56 works. Then it sort of sticks. But if I also change width (default is from CONSOLE), I can increase max_position further.

I was testing this with a long parser argument. Adding

parser.add_argument('-l','--long','--longlonglonglong', help='help after long option strings')

produces:

usage: issue25297.py [-h] [-l LONG] <command> ... optional arguments: -h, --help show this help message and exit -l LONG, --long LONG, --longlonglonglong LONG help after long option strings Commands: <command> long_long_long_long_long_long_long - jksljdalkjda

So max_help_position does work in regular parser formatting. But for some reason, when only the subparser names are long, it does not. That section requires some special formatting. It is indented, and the subparser names are not real actions (arguments) but rather choices the subparsers argument. I'll have study it in more detail.

The subparser name string is indented 2 extra characters (compared to other arguments). The code that collects self._action_max_length does not take this into account. Hence if the subparser name is the longest string, this max_length will end up 2 spaces short. Compare actual v desired:

long_long_long_long_long_long_long - jksljdalkjda long_long_long_long_long_long_long - jksljdalkjda

(Formatting is done in 2 steps; once to calculate values like this _action_max_length, and a 2nd time to produce the actual output).

Subparsers are formatted with a recursive call to _format_action, so I'm not optimistic about an easy fix.

Corrected formatter

Here's a patched Formatter that correctly accounts for the indenting of subactions (sub parsers). When an argument (action) is added to the Formatter, this function figures how wide its invocation strings are, and adjusts self._max_action_length. This is used latter to indent the help strings.

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])

An example of its use (without going real wide):

# call class with alternate parameters formatter_class=lambda prog: MyFormatter(prog, max_help_position=40,width=100) parser = argparse.ArgumentParser(formatter_class=formatter_class) parser.add_argument('-l','--long', help='help after long option strings') subparsers = parser.add_subparsers(title="Commands", metavar="<command>") cmd_parser = subparsers.add_parser('long_long_cmd', help='longish command', formatter_class=formatter_class, aliases=['long', 'long_cmd']) # newer arpgarse take aliases sht_parser = subparsers.add_parser('short', help = 'short cmd') args = parser.parse_args(['-h'])

which displays:

usage: issue25297.py [-h] [-l LONG] <command> ... optional arguments: -h, --help show this help message and exit -l LONG, --long LONG help after long option strings Commands: <command> long_long_cmd (long, long_cmd) longish command short short cmd

Từ khóa » Thư Viện Argparse Trong Python