When you look at the parse_args() implementation , you will notice that it parses all the arguments at once (it does not use yield to continuously generate state), so you need to prepare your structure before and after half of the arguments have been parsed.
Taking from an official example in the docs , you should add subparser (s) before starting the parsing as follows:
import argparse parser = argparse.ArgumentParser(prog='PROG') subparsers = parser.add_subparsers(help='sub-command help')
And the output (on the command line), the help is beautifully printed:
D:\tmp>s.py -h usage: PROG [-h] {a,b} ... positional arguments: {a,b} sub-command help aa help bb help optional arguments: -h, --help show this help message and exit
Arguments are analyzed
D:\tmp>s.py a --opt1 Namespace(opt1=True, opt2=False)
Parsed arguments B
D:\tmp>s.py b Namespace(opt3=False, opt4=False)
Also with args:
D:\tmp>s.py b --opt3 Namespace(opt3=True, opt4=False)
Running arguments in B result in an error:
D:\tmp>s.py b --opt2 usage: PROG [-h] {a,b} ... PROG: error: unrecognized arguments: --opt2
Also, if you need to determine which subparameter was used, you can add the dest=name call to parser.add_subparsers() (which, it seems to me, is not properly underlined in the documents):
subparsers = parser.add_subparsers(help='sub-command help', dest='subparser_name')
As a result:
D:\tmp>s.py b --opt3 Namespace(opt3=True, opt4=False, subparser_name='b')
If you needed to dynamically create arguments (for example, load some argument parameters from an expensive resource), you can use parse_known_args() :
Sometimes a script can parse only a few command line arguments, passing the remaining arguments to another script or program. In these cases, the parse_known_args() method may be useful. It works the same as parse_args() , except that it does not throw an error if there are additional arguments. Instead, it returns a binary tuple containing the filled namespace and a list of the remaining argument strings .
In the end, parse_args() just checks for trailing aruments:
def parse_args(self, args=None, namespace=None): args, argv = self.parse_known_args(args, namespace) if argv: msg = _('unrecognized arguments: %s') self.error(msg % ' '.join(argv)) return args
And then you can re-execute another parser on argv , but I can imagine a few problems that could go with this, and I would not recommend it until it really is needed.