I'm trying to figure out how to use properly builtin argparse module to get a similar output than tools such as git where I can display a nice help with all "root commands" nicely grouped, ie:
$ git --help
usage: git [--version] [--help] [-C <path>] [-c <name>=<value>]
[--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
[-p | --paginate | -P | --no-pager] [--no-replace-objects] [--bare]
[--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
[--super-prefix=<path>] [--config-env=<name>=<envvar>]
<command> [<args>]
These are common Git commands used in various situations:
start a working area (see also: git help tutorial)
clone Clone a repository into a new directory
init Create an empty Git repository or reinitialize an existing one
work on the current change (see also: git help everyday)
add Add file contents to the index
mv Move or rename a file, a directory, or a symlink
restore Restore working tree files
rm Remove files from the working tree and from the index
examine the history and state (see also: git help revisions)
bisect Use binary search to find the commit that introduced a bug
diff Show changes between commits, commit and working tree, etc
grep Print lines matching a pattern
log Show commit logs
show Show various types of objects
status Show the working tree status
grow, mark and tweak your common history
branch List, create, or delete branches
commit Record changes to the repository
merge Join two or more development histories together
rebase Reapply commits on top of another base tip
reset Reset current HEAD to the specified state
switch Switch branches
tag Create, list, delete or verify a tag object signed with GPG
collaborate (see also: git help workflows)
fetch Download objects and refs from another repository
pull Fetch from and integrate with another repository or a local branch
push Update remote refs along with associated objects
'git help -a' and 'git help -g' list available subcommands and some
concept guides. See 'git help <command>' or 'git help <concept>'
to read about a specific subcommand or concept.
See 'git help git' for an overview of the system.
Here's my attempt:
from argparse import ArgumentParser
class FooCommand:
def __init__(self, subparser):
self.name = "Foo"
self.help = "Foo help"
subparser.add_parser(self.name, help=self.help)
class BarCommand:
def __init__(self, subparser):
self.name = "Bar"
self.help = "Bar help"
subparser.add_parser(self.name, help=self.help)
class BazCommand:
def __init__(self, subparser):
self.name = "Baz"
self.help = "Baz help"
subparser.add_parser(self.name, help=self.help)
def test1():
parser = ArgumentParser(description="Test1 ArgumentParser")
root = parser.add_subparsers(dest="command", description="All Commands:")
# Group1
FooCommand(root)
BarCommand(root)
# Group2
BazCommand(root)
args = parser.parse_args()
print(args)
def test2():
parser = ArgumentParser(description="Test2 ArgumentParser")
# Group1
cat1 = parser.add_subparsers(dest="command", description="Category1 Commands:")
FooCommand(cat1)
BarCommand(cat1)
# Group2
cat2 = parser.add_subparsers(dest="command", description="Category2 Commands:")
BazCommand(cat2)
args = parser.parse_args()
print(args)
If you run test1 you'd get:
$ python mcve.py --help
usage: mcve.py [-h] {Foo,Bar,Baz} ...
Test1 ArgumentParser
options:
-h, --help show this help message and exit
subcommands:
All Commands:
{Foo,Bar,Baz}
Foo Foo help
Bar Bar help
Baz Baz help
Obviously this is not what I want, in there I just see all commands in a flat list, no groups or whatsoever... so the next logical attempt would be trying to group them. But if I run test2 I'll get:
$ python mcve.py --help
usage: mcve.py [-h] {Foo,Bar} ...
mcve.py: error: cannot have multiple subparser arguments
Which obviously means I'm not using properly argparse to accomplish the task at hand. So, is it possible to use argparse to achieve a similar behaviour than git? In the past I've relied on "hacks" so I thought the best practice here would be using the concept of add_subparsers but it seems I didn't understand properly that concept.
gitdoesn't useargparse, so don't expect to duplicate it.argparselets you group arguments (with 2 default groups). It does not provide a way of grouping subparsers.subparsers? 🤔