Reputation: 3108
In argparse, I want to prevent a particular combination of arguments. Lets see the sample code.
import argparse
parser = argparse.ArgumentParser(add_help=False)
parser.add_argument('--firstname', dest='fn', action='store')
parser.add_argument('--lastname', dest='ln', action='store')
parser.add_argument('--fullname', dest='full', action='store')
args = parser.parse_args()
For eg: --firstname --lastname --fullname
The user can run the code in 2 days.
code.py --firstname myfirst --lastname mylast
code.py --fullname myfullname
We should not use the combination fistname, fullname
or lastname, fullname
. If we use both, then it should not execute.
Can someone help me to fix this?
Upvotes: 1
Views: 1614
Reputation: 39
A simple solution I've found useful if:
In the below example, I prevented a combination of '--horizontal left' and '--vertical up' in the 'move' subparser:
import argparse
# Custom action to prevent a combination of '--horizontal left' and '--vertical up'
class PreventUpLeftStoreAction(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
setattr(namespace, self.dest, values)
if namespace.horizontal == 'left' and namespace.vertical == 'up':
parser.error("invalid combination of arguments: '--horizontal left' and '--vertical up' are not allowed together")
parser = argparse.ArgumentParser(description='Main Parser')
subparsers = parser.add_subparsers()
parser_move = subparsers.add_parser('move')
parser_move.add_argument('--horizontal', action=PreventUpLeftStoreAction, choices=['left', 'right'], required=True)
parser_move.add_argument('--vertical', action=PreventUpLeftStoreAction, choices=['up', 'down'], required=True)
args = parser.parse_args()
print(args)
Upvotes: 1
Reputation: 470
Like this answer proposes (on a similar question) you can do something like the following by using subparsers for both cases:
# create the top-level parser
parser = argparse.ArgumentParser(add_help=false)
subparsers = parser.add_subparsers(help='help for subcommands')
# create the parser for the "full_name" command
full_name = subparsers.add_parser('full_name', help='full_name help')
full_name.add_argument('--fullname', dest='full', action='store')
# create the parser for the "separate_names" command
separate_names = subparsers.add_parser('separate_names', help='separate_names help')
separate_names.add_argument('--firstname', dest='fn', action='store')
separate_names.add_argument('--lastname', dest='ln', action='store')
args = parser.parse_args()
You can improve it even further by requiring both the first and last name of the user as it generally makes sense.
Upvotes: 1
Reputation: 54
You can split your arguments into separate commands and use subparsers, for example:
import argparse
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
parser_clean = subparsers.add_parser('clean', description='clean build folder')
parser_clean.add_argument('--all', help='clean build folder and logs', action='store_true')
parser_deploy = subparsers.add_parser('deploy')
parser_deploy.add_argument('object')
parser_deploy.add_argument('--nc', help='no cleanup', action='store_true')
args = parser.parse_args()
Upvotes: 1
Reputation: 2143
Not sure that is an argparse specific behavior that is possible. But as long as those items are going to their own variables in the argparse resposes its a simple set of programming to check which ones are set and issue a message and exit.
example (assuming the result of parsing is in argsvalue):
if argsvalue.fullname and (argsvalue.firstname or argsvalue.lastname):
print ("missuse of name options.....")
This assumes the argparse default for the vars is None (then if anything is set in them they will test to true with the logic above...
Upvotes: 2