Search code examples
pythonargparse

Create Mutual Inclusive arguments with argparse


I want to build a program that has 2 mutually inclusive args and 2 that are not dependent on the first two. Something like this:

consume [--count n] | show | clear

where 'consume' and '--count' are dependent on each other i.e, without 'consume' '--count' will throw an error 'show' and 'clear' do not depend on the first consume and --count.

Edit: show and clear are optional arguments

Here's what I was able to do till now:

import argparse
parser = argparse.ArgumentParser()
group = argparse.ArgumentParser(usage='%(prog)s [consume [--count]]')
group.add_argument('consume', help='mutually inclusive with count')
group.add_argument('--count', type = int, help='get the count n')

parser.add_argument('show', help='show the messages')
parser.add_argument('clear', help='clear messages from db')

args = group.parse_args()
args1 = parser.parse_args()

if args.count and not args.consume:
    parser.error('the following arguments are required: consume')
else:
    print(args.count)
    print(args1.show)
    print(args1.clear)

So when the run the command, without consume:

[filename] --count 7 show clear

I get the following error:

unrecognized arguments: clear

Can someone help me with making the arguments mutually inclusive and other arguments not dependent on them?


Solution

  • You could try something like this...

    Add a MutuallyInclusiveArgumentError Exception subclass, then split the arguments in an argument group, and check for errors after parsing has been completed.

    import argparse
    import sys
    class MutuallyInclusiveArgumentError(Exception):
        pass
    
    parser = argparse.ArgumentParser(sys.argv[0])
    subs = parser.add_argument_group("mutually inclusive")
    subs.add_argument('--consume', help='mutually inclusive with count', action='store_true')
    subs.add_argument('--count', type = int, help='get the count n')
    parser.add_argument('--show', help='show the messages', action='store_true')
    parser.add_argument('--clear', help='clear messages from db', action='store_true')
    
    
    args = parser.parse_args()
    if args.count and args.consume is False:
        raise MutuallyInclusiveArgumentError("--count option must be used with the --consume option" )
    
    
    
    print(vars(args))
    
    

    the help message looks like this

    usage: {progname} [-h] [--consume] [--count COUNT] [--show] [--clear]
    
    options:
      -h, --help     show this help message and exit
      --show         show the messages
      --clear        clear messages from db
    
    mutually inclusive:
      --consume      mutually inclusive with count
      --count COUNT  get the count n