I have a script that has multiple commands, with each command taking it's own set of required and/or optional arguments, by using add_subparser.
=->test.py -h
usage: test.py [-h] <command> ...
positional arguments:
<command> Available Commands
cmd1 Command 1
cmd2 Command 2
cmd3 Command 3
cmd4 Command 4
optional arguments:
-h, --help show this help message and exit
=->test.py cmd1 -h
usage: test.py cmd1 [-h] --flag1 FLAG1
optional arguments:
-h, --help show this help message and exit
--flag1 FLAG1 Test flag
=->test.py cmd2 -h
usage: test.py cmd2 [-h] [--flag2 FLAG2]
optional arguments:
-h, --help show this help message and exit
--flag2 FLAG2 Test flag
I'd like to somehow separate these commands into groups so that users see something like the following:
=->test.py -h
usage: test.py [-h] <command> ...
First Group:
cmd1 Command 1
cmd2 Command 2
Second Group:
cmd3 Command 3
cmd4 Command 4
optional arguments:
-h, --help show this help message and exit
But, doesn't look like add_argument_group and add_subparsers work together.
Any way to achieve this?
After importing the library, argparse. ArgumentParser() initializes the parser so that you can start to add custom arguments. To add your arguments, use parser. add_argument() .
A “subparser” is an argument parser bound to a namespace. In other words, it works with everything after a certain positional argument. Argh implements commands by creating a subparser for every function.
>>> parser = argparse.ArgumentParser(description='Process some integers.') The ArgumentParser object will hold all the information necessary to parse the command line into Python data types.
The store_true option automatically creates a default value of False. Likewise, store_false will default to True when the command-line argument is not present. The source for this behavior is succinct and clear: http://hg.python.org/cpython/file/2.7/Lib/argparse.py#l861.
You are right, argument groups and subparsers don't work together. That's because subparsers (or rather their names) are not arguments.
The sp = parser.add_subparsers(...)
command creates an argument, or technically an instance of a subclass of argparse.Action
. This is a positional argument. The add_parser
command creates a parser
object (i.e. calls argparse.ArgumentParser
), and adds it, along with its name (and aliases) to a dictionary owned by this action. And the names populate the choices
attribute of the Action.
That subparsers
Action could belong to an argument group, but since there can only be one such action, it doesn't help you group the help lines.
You can control, to some extent, the help by using a description, and omitting the help for subparsers
import argparse
description = """
First Group:
cmd1 Command 1
cmd2 Command 2
Second Group:
cmd3 Command 3
cmd4 Command 4"""
parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter)
sp = parser.add_subparsers(title='commands',description=description)
sp.add_parser('cmd1')
sp.add_parser('cmd2')
sp.add_parser('cmd3')
sp.add_parser('cmd4')
parser.print_help()
produces
1343:~/mypy$ python stack32017020.py
usage: stack32017020.py [-h] {cmd1,cmd2,cmd3,cmd4} ...
optional arguments:
-h, --help show this help message and exit
commands:
First Group:
cmd1 Command 1
cmd2 Command 2
Second Group:
cmd3 Command 3
cmd4 Command 4
{cmd1,cmd2,cmd3,cmd4}
http://bugs.python.org/issue9341 - allow argparse subcommands to be grouped
talks about doing what you want. The patch that I proposed isn't trivial. But you are welcome to test it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With