1

I would like to write a Python script called sync that has three or four modes of operation, each receiving a different number of arguments. For example,

sync set_version <build> <version_number>
sync get_version <build>
sync has_started <build_1> <build_2> ... <build_n>

I've tried using argparse's subparsers for each mode of operation:

import argparse

parser = argparse.ArgumentParser(description='Build synchronization mechanism')
subparsers = parser.add_subparsers()

parser_get_version = subparsers.add_parser('get_version')
parser_get_version.add_argument('build')

parser_update_version = subparsers.add_parser('update_version')
parser_update_version.add_argument('build')
parser_update_version.add_argument('version')

args = parser.parse_args()
print args

The problem is that the help message is not reflecting the structure of the arguments of each operation modes. Instead, it simply lists the operation modes:

usage: sync.py [-h] {get_version,update_version} ...

Build synchronization mechanism

positional arguments:
  {get_version,update_version}

optional arguments:
  -h, --help            show this help message and exit

How do I force argparse to display a full help message, with all the subparsers parameters?

Adam Matan
  • 128,757
  • 147
  • 397
  • 562
  • This might be relevant: http://stackoverflow.com/questions/14918804/how-to-show-help-for-all-subpasers-in-argparse – jsalonen Jul 24 '13 at 19:39
  • You might want to check out [`docopt`](http://docopt.org/) for this job - I hear good things about the library. You give a description in a similar style to the help you normally get, and it automatically parses the command line args into a simple data structure, and it appears to output the help as you want it to. – Gareth Latty Jul 24 '13 at 19:40

1 Answers1

1

Each sub-command has it's own help; try sync.py get_version --help, for example.

You'd have to override the help action yourself, and loop over the subcommands and print help for each. This requires some foibling with internal attributes:

class HelpAction(argparse._HelpAction):
     def __call__(self, parser, namespace, values, option_string=None):
         parser.print_help()

         for group in parser._subparsers._group_actions:
             group.choices.values()[0].print_help()

         parser.exit()

parser = argparse.ArgumentParser(description='Build synchronization mechanism',
                                 add_help=False)
parser.add_argument('-h', '--help', action=HelpAction, default=argparse.SUPPRESS,
    help=argparse._('show this help message and exit'))

You probably want to tweak the output some more though.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343