Generally, you should avoid making --options required. In this case, I would suggest the following:
- Replace
--mode with a subcommand.
- Replace
-d with a positional argument
- Replace
-f with a 2nd positional argument for the download command only.
If you really want to, you can keep -d and -f instead of making them positional arguments.
Your calls would look like this:
./script.py upload d-argument
./script.py download d-argument f-argument
or
./script.py upload -d foo
./script.py download -d foo -f bar
The code to implement is a little tedious, but fairly straightforward.
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
upload_parser = subparsers.add_parser('upload')
download_parser = subparsers.add_parser('download')
upload_parser.set_defaults(cmd='upload')
download_parser.set_defaults(cmd='download')
for p in [ upload_parser, download_parser ]:
p.add_argument("d")
# p.add_argument("-d", required=True)
download_parser.add_argument("f")
# download_parser.add_argument("-f", required=True)
args = parser.parse_args()
if args.cmd == 'upload':
# handle upload with args.d
elif args.cmd == 'download':
# handle download with args.d and args.f
Note the calls to set_defaults used to mark in the final parsed arguments which command was used.
argparsedoes not have mutually inclusive arguments, which is what you are talking about. You should instead make neither-dnor-fbe required, but include in the usage message the fact that either both or neither must be specified, then check to make sure that both-dand-fare specified if either is.downloadbecomes a subcommand with it's own set of (required) flags.