Reputation: 855
I am creating a python script and for parsing the arguments I would need this: the script will accept three parameters, only one always mandatory, the second one will only be mandatory depending on certain values of the first one and the third one may or may not appear. This is my try:
class pathAction(argparse.Action):
folder = {'remote':'/path1', 'projects':'/path2'}
def __call__(self, parser, args, values, option = None):
args.path = values
print "ferw %s " % args.component
if args.component=='hos' or args.component=='hcr':
print "rte %s" % args.path
if args.path and pathAction.folder.get(args.path):
args.path = pathAction.folder[args.path]
else:
parser.error("You must enter the folder you want to clean: available choices[remote, projects]")
def main():
try:
# Arguments parsing
parser = argparse.ArgumentParser(description="""This script will clean the old component files.""")
parser.add_argument("-c", "--component", help="component to clean", type=lowerit, choices=["hos", "hcr", "mdw", "gui"], required=True)
parser.add_argument("-p", "--path", help="path to clean", action = pathAction, choices = ["remote", "projects"])
parser.add_argument("-d", "--delete", help="parameter for deleting the files from the filesystem", nargs='*', default=True)
args = parser.parse_args()
if works well except one case: if i have -c it should complain because there is no -p however it does not Can you help me please? Thanks
Upvotes: 0
Views: 325
Reputation: 231738
Your special action
will be used only if there is a -p
argument. If you just give it a -c
the cross check is never used.
Generally checking for interactions after parse_args
(as Gohn67
suggested) is more reliable, and simpler than with custom actions.
What happens if your commandline was '-p remote -c ...'
? pathAction
would be called before the -c
value is parsed and set. Is that what you want? Your special action only works if -p
is given, and is the last argument.
Another option is to make 'component' a subparser positional. By default positionals are required. path
and delete
can be added to those subparsers that need them.
import argparse
parser = argparse.ArgumentParser(description="""This script will clean the old component files.""")
p1 = argparse.ArgumentParser(add_help=False)
p1.add_argument("path", help="path to clean", choices = ["remote", "projects"])
p2 = argparse.ArgumentParser(add_help=False)
p2.add_argument("-d", "--delete", help="parameter for deleting the files from the filesystem", nargs='*', default=True)
sp = parser.add_subparsers(dest='component',description="component to clean")
sp.add_parser('hos', parents=[p1,p2])
sp.add_parser('hcr', parents=[p1,p2])
sp.add_parser('mdw', parents=[p2])
sp.add_parser('gui', parents=[p2])
print parser.parse_args()
sample use:
1848:~/mypy$ python2.7 stack21625446.py hos remote -d 1 2 3
Namespace(component='hos', delete=['1', '2', '3'], path='remote')
I used parents
to simplify adding arguments to multiple subparsers. I made path
a positional, since it is required (for 2 of the subparsers). In those cases --path
just makes the user type more. With nargs='*'
, --delete
has to belong to the subparsers so it can occur last. If it's nargs
was fixed (None
or number) it could be an argument of parser
.
Upvotes: 0
Reputation: 10648
You can add some custom validation like this:
if args.component and not args.path:
parser.error('Your error message!')
Upvotes: 1