How to parse multiple nested sub-commands using python argparse?

argparse, command-line-arguments, python

Solution

@mgilson has a nice answer to this question. But problem with splitting sys.argv myself is that I lose the nice help message `Argparse` generates for the user. So I ended up doing this:

import argparse

## This function takes the 'extra' attribute from global namespace and
## re-parses it to create separate namespaces for all other chained commands.
def parse_extra (parser, namespace):
  namespaces = []
  extra = namespace.extra
  while extra:
    n = parser.parse_args(extra)
    extra = n.extra
    namespaces.append(n)

  return namespaces

argparser=argparse.ArgumentParser()
subparsers = argparser.add_subparsers(help='sub-command help', dest='subparser_name')

parser_a = subparsers.add_parser('command_a', help = "command_a help")
## Setup options for parser_a

## Add nargs="*" for zero or more other commands
argparser.add_argument('extra', nargs = "*", help = 'Other commands')

## Do similar stuff for other sub-parsers

Now after first parse all chained commands are stored in `extra`. I reparse it while it is not empty to get all the chained commands and create separate namespaces for them. And i get nicer usage string that argparse generates.

Problem

I am implementing a command line program which has interface like this: ``` cmd [GLOBAL_OPTIONS] {command [COMMAND_OPTS]} [{command [COMMAND_OPTS]} ...] ``` I have gone through the argparse documentation. I can implement `GLOBAL_OPTIONS` as optional argument using `add_argument` in `argparse`. And the `{command [COMMAND_OPTS]}` using Sub-commands. From the documentation it seems I can have only one sub-command. But as you can see I have to implement one or more sub-commands. What is the best way to parse such command line arguments useing `argparse`?

Original source

Related problems