I have an argparse
program with multiple subparsers. IF the value of a top-level argument is not specified, I would like it to depend on the subparser selection. This can be partially accomplished by using set_defaults()
on each subparser. However, the passed value does NOT act like a true default in that it takes precedence even when the top-level argument is explicitly provided.
Am I missing something in the argparse
module that would allow the subparser-specific defaults to yield to the top-level parser? Below is a toy example which demonstrates my desired use case
import argparse
# Top-level parser
parser = argparse.ArgumentParser()
parser.add_argument('-t', '--time', type=str)
# Add subparsers with options
actions = parser.add_subparsers(dest='action', metavar='action')
actions.required = True
eat = actions.add_parser('eat')
eat.add_argument('-f', '--food', type=str, default='pizza')
order = actions.add_parser('order')
order.add_argument('-i', '--item', type=int, required=True)
# Attempt to set main parser's --time depending on subparser selection
eat.set_defaults(time='now')
order.set_defaults(time='later')
# Tests that work as expected
print(parser.parse_args(['order', '--item', 0])) # Namespace(action='order', item=0, time='later')
print(parser.parse_args(['eat'])) # Namespace(action='eat', food='pizza', time='now')
# Tests that DO NOT work
# Actual result: the --time flag of `parser` is ignored in preference of each subparser's default
# Desired result: explicit usage of --time should override the subparser defaults like the comments below
# Namespace(action='order', item=0, time='before')
# Namespace(action='eat', food='pizza', time='after')
print(parser.parse_args(['--time', 'before', 'order', '--item', 0]))
print(parser.parse_args(['--time', 'after', 'eat']))