Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grouping argparse subparser arguments

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?

like image 662
Pavel Chernikov Avatar asked Aug 14 '15 18:08

Pavel Chernikov


People also ask

How do you pass arguments to Argparse?

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() .

What is Subparser?

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.

What does Argparse ArgumentParser () do?

>>> 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.

What is Store_true in Python?

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.


1 Answers

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.

like image 103
hpaulj Avatar answered Oct 24 '22 21:10

hpaulj