I have done as much research as possible but I haven't found the best way to make certain cmdline arguments necessary only under certain conditions, in this case only if other arguments have been given. Here's what I want to do at a very basic level:
p = argparse.ArgumentParser(description='...') p.add_argument('--argument', required=False) p.add_argument('-a', required=False) # only required if --argument is given p.add_argument('-b', required=False) # only required if --argument is given   From what I have seen, other people seem to just add their own check at the end:
if args.argument and (args.a is None or args.b is None):     # raise argparse error here   Is there a way to do this natively within the argparse package?
I've been searching for a simple answer to this kind of question for some time. All you need to do is check if '--argument' is in sys.argv, so basically for your code sample you could just do:
import argparse import sys  if __name__ == '__main__':     p = argparse.ArgumentParser(description='...')     p.add_argument('--argument', required=False)     p.add_argument('-a', required='--argument' in sys.argv) #only required if --argument is given     p.add_argument('-b', required='--argument' in sys.argv) #only required if --argument is given     args = p.parse_args()   This way required receives either True or False depending on whether the user as used --argument. Already tested it, seems to work and guarantees that -a and -b have an independent behavior between each other.
You can implement a check by providing a custom action for --argument, which will take an additional keyword argument to specify which other action(s) should become required if --argument is used.
import argparse  class CondAction(argparse.Action):     def __init__(self, option_strings, dest, nargs=None, **kwargs):         x = kwargs.pop('to_be_required', [])         super(CondAction, self).__init__(option_strings, dest, **kwargs)         self.make_required = x      def __call__(self, parser, namespace, values, option_string=None):         for x in self.make_required:             x.required = True         try:             return super(CondAction, self).__call__(parser, namespace, values, option_string)         except NotImplementedError:             pass  p = argparse.ArgumentParser() x = p.add_argument("--a") p.add_argument("--argument", action=CondAction, to_be_required=[x])   The exact definition of CondAction will depend on what, exactly, --argument should do. But, for example, if --argument is a regular, take-one-argument-and-save-it type of action, then just inheriting from argparse._StoreAction should be sufficient.
In the example parser, we save a reference to the --a option inside the --argument option, and when --argument is seen on the command line, it sets the required flag on --a to True. Once all the options are processed, argparse verifies that any option marked as required has been set.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With