Here is another attempt to write a custom Action class
import argparse class FooAction(argparse.Action): # adapted from documentation def __call__(self, parser, namespace, values, option_string=None): setattr(namespace, self.dest, values) defaultbar = getattr(namespace, 'bar') try: defaultbar = defaultbar%values except TypeError: # BAR has already been replaced pass setattr(namespace, 'bar', defaultbar) parser = argparse.ArgumentParser() parser.add_argument("--foo", required=True, action=FooAction) parser.add_argument("--bar", default="%s_BAR") args = parser.parse_args(['--foo', 'Foo', '--bar', 'Bar']) # Namespace(bar='Bar', foo='Foo') args = parser.parse_args(['--foo', 'Foo']) # Namespace(bar='Foo_BAR', foo='Foo') args = parser.parse_args(['--bar', 'Bar', '--foo', 'Foo']) # Namespace(bar='Bar', foo='Foo')
Note that the class must know the dest argument to --bar . In addition, I use '%s_BAR' to easily distinguish between the default value and the default value. This handles the case when --bar appears before --foo .
All that complicates this approach:
- default values ββare evaluated at
add_argument time. - default values ββare placed in the namespace at the beginning of
parse_args . - tagged (optional) arguments can occur in any order
- the
Action class is not intended to handle interacting arguments. - The
bar action will not be called in the default case. - The default
bar value may be a function, but after parse_args you need to check if it needs to be evaluated or not.
While this regular action does the trick, I still think the addbar function in my other answer is a cleaner solution.
hpaulj
source share