Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Customize help among groups in argparse

I'm using argparse and I have various groups which have set of its own options.

Now with the --help option I do not want to show all the options by default. Only a set of groups options are to be shown for --help.

Other group options should be shown based on other help options, as --help_1, --help_2:

For example:

--help' to show Group 2 and 3
--help_1' to show Group 11 and 12
--help_2' to show Group 22 and 23

I know that we can disable the default --help option with using add_help=False but how do I get to display only selected group specific helps.

We can get the list of groups from the parser using _action_groups attribute, but they do not expose any print_help() option as such.

My sample code:

parser = argparse.ArgumentParser(add_help=False)

parser.add_argument('--help_a', action='store_true')
parser.add_argument('--help_b', action='store_true')

group1 = parser.add_argument_group("Feature 1")
group1.add_argument('--foo1')
group2 = parser.add_argument_group("Feature 2")
group2.add_argument('--foo2')
group3 = parser.add_argument_group("Feature 3")
group3.add_argument('--foo3')

# TODO: --help_a to only print "Feature 1" groups help
# and --help_b to print Feature 2 and 3's help.

EDIT: Using subparser and adding parsers(instead of group) will solve the above. But subparser doesn't fit in my case, as I am parsing it always, I only need to customize help to be displayed.

like image 749
baky Avatar asked Jan 18 '26 04:01

baky


1 Answers

Here's the custom format_help approach:

import argparse

def format_help(self, groups=None):
    # self == parser
    formatter = self._get_formatter()

    # usage
    formatter.add_usage(self.usage, self._actions,
                        self._mutually_exclusive_groups)

    # description
    formatter.add_text(self.description)

    if groups is None:
        groups = self._action_groups

    # positionals, optionals and user-defined groups
    for action_group in groups:
        formatter.start_section(action_group.title)
        formatter.add_text(action_group.description)
        formatter.add_arguments(action_group._group_actions)
        formatter.end_section()

    # epilog
    formatter.add_text(self.epilog)

    # determine help from format above
    return formatter.format_help()

<your parser>

args = parser.parse_args()
# _action_groups[:2] are the default ones
if args.help_a:
    print(format_help(parser, [parser._action_groups[2]]))
    parser.exit()
if args.help_b:
    print(format_help(parser, parser._action_groups[3:]))
    parser.exit()

Sample runs

1444:~/mypy$ python stack40718566.py --help_a
usage: stack40718566.py [-h] [--help_a] [--help_b] [--foo1 FOO1] [--foo2 FOO2]
                        [--foo3 FOO3]

Feature 1:
  --foo1 FOO1

1444:~/mypy$ python stack40718566.py --help_b
usage: stack40718566.py [-h] [--help_a] [--help_b] [--foo1 FOO1] [--foo2 FOO2]
                        [--foo3 FOO3]

Feature 2:
  --foo2 FOO2

Feature 3:
  --foo3 FOO3

So it's just like the default format_help, except it takes a groups parameter. It could even replace the default method in an ArgumentParser subclass.

We could also create a custom Help Action class that behaves like the standard help, except that it takes some sort of group_list parameter. But this post-parsing action is simpler to code and test.

like image 124
hpaulj Avatar answered Jan 19 '26 18:01

hpaulj



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!