I have an argparse
parser with several subcommands some of which share an option (via a parent parser). Now I want to set a default value for such an option regardless of which subparser will be executed in the end. My non working code looks like this:
from argparse import ArgumentParser
base = ArgumentParser(add_help=False)
base.add_argument('--foo', action='store_true')
parser = ArgumentParser()
subparsers = parser.add_subparsers(dest='action')
s1 = subparsers.add_parser('a', parents=[base])
s2 = subparsers.add_parser('b', parents=[base])
parser.set_defaults(foo=42)
print(parser.parse_args(['a']))
s1.set_defaults(foo=43)
print(parser.parse_args(['a']))
This prints
Namespace(action='a', foo=False)
Namespace(action='a', foo=43)
I have many subparsers and many options so I want to avoid saving every subparser by name and calling set_defauls
on it. Can that be done?
I will know the value I want to set there only after creating all the parsers so I can not specify the defaults in the call to add_argument
.
Background: what I am actually working on
The defaults I want to set come from a config file. I actually have two parsers, one to find the config file first and one to parse the subcommands. But I need to define both parsers up front in order to overwrite the help method of the first parser with the help method of the second parser in order to display the full --help
text before parsing the config (because that might fail and I could not display the help text). A reduced version of my code looks like this:
import argparse
base = argparse.ArgumentParser(add_help=False)
base.add_argument("--config", help="config file to use")
p1 = argparse.ArgumentParser(parents=[base])
p1.add_argument('remainder', nargs=argparse.REMAINDER)
p2 = argparse.ArgumentParser(parents=[base])
s = p2.add_subparsers(dest='action')
s1 = s.add_parser('a') # add some options
s2 = s.add_parser('b') # add some options
# and so on
p1.print_help = p2.print_help
a1 = p1.parse_args()
config = load_my_config(a1.config)
p2.set_defaults(**config.get_my_defaults())
a2 = p2.parse_args(a1.remainder)