Skip to content Skip to sidebar Skip to footer

How To Make At Least One Argument Required And Have The Possibility To Take All Arguments With Argparse In Python?

The program has 2 arguments to deal with: state and key. I need to have a possibility to give as input the following options: prog -state state_value prog -key key_value prog -sta

Solution 1:

As noted in https://stackoverflow.com/a/24911007/901925 there isn't a built in mechanism for testing this, but it is easy to make such a test after parsing. Assuming the arguments have the default default of None, such a test could be:

if args.state is None and args.keyis None:
    parser.error('At least one of the arguments is required ')

Eventually argparse might have such a mechanism. There is a bug request for more testing power in groups, http://bugs.python.org/issue11588

One idea is to add UsageGroups, modeled on mutually exclusive groups, but with more general logic. The code isn't available for download, but I'd be interested in hearing whether this example is clear.

parser = argparse.ArgumentParser(prog='prog')
group = parser.add_usage_group(kind='any', required=True)
group.add_argument('-s', '--state', metavar='state_value')
group.add_argument('-k', '--key', metavar='key_value')
args = parser.parse_args()
print(args)

with an error message:

usage: prog [-h] (-s state_value | -k key_value)
prog:error: group any(): some of the arguments [state, key] is required

An alternative in the usage line is (-s state_value, -k key_value), since | is already being used for the mutually exclusive xor relation. The usage and error message could be customized.

Solution 2:

I think this is beyond the abilities of argparse. You could perform a simple validation on the returned namespace afterwards though. You should include in your help that at least once of state or key is required.

def validate(namespace, parser):
    if not any(arg in {"state", "key"} for arg in vars(namespace).keys()):
        parser.print_help()
        parser.exit(2)

namespace = parser.parse_args()
validate(namespace, parser)

Solution 3:

#!/usr/bin/python#-*- coding:utf-8 -*-import sys

paras = sys.argv.pop(0)
state_value = None
key_value = None
i=0while i < len(paras):
    if paras[i] == '-state':
        state_value = paras[i]
    elif paras[i] == '-key':
        key_value = paras[i]
    i += 2if state_value:
    # do somethingpassif key_value:
    # do somethingpass

Post a Comment for "How To Make At Least One Argument Required And Have The Possibility To Take All Arguments With Argparse In Python?"