I have quite a big program which has a CLI interaction based on argparse
, with several sub parsers. The list of supported choices for the subparsers arguments a
To delay the fetching of choices, you could parse the command-line in two stages: In the first stage, you find only the subparser, and in the second stage, the subparser is used to parse the rest of the arguments:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('subparser', choices=['foo','bar'])
def foo_parser():
parser = argparse.ArgumentParser()
parser.add_argument('fooval', choices='123')
return parser
def bar_parser():
parser = argparse.ArgumentParser()
parser.add_argument('barval', choices='ABC')
return parser
dispatch = {'foo':foo_parser, 'bar':bar_parser}
args, unknown = parser.parse_known_args()
args = dispatch[args.subparser]().parse_args(unknown)
print(args)
It could be used like this:
% script.py foo 2
Namespace(fooval='2')
% script.py bar A
Namespace(barval='A')
Note that the top-level help message will be less friendly, since it can only tell you about the subparser choices:
% script.py -h
usage: script.py [-h] {foo,bar}
...
To find information about the choices in each subparser, the user would have to select the subparser and pass the -h
to it:
% script.py bar -- -h
usage: script.py [-h] {A,B,C}
All arguments after the --
are considered non-options (to script.py
) and are thus parsed by the bar_parser
.