I've been using argparse
for a Python program that can -process
, -upload
or both:
parser = argparse.ArgumentParser(description='Log archiver arguments.')
parser.add_argument('-process', action='store_true')
parser.add_argument('-upload', action='store_true')
args = parser.parse_args()
The program is meaningless without at least one parameter. How can I configure argparse
to force at least one parameter to be chosen?
UPDATE:
Following the comments: What's the Pythonic way to parametrize a program with at least one option?
This achieves the purpose and this will also be relfected in the argparse autogenerated
--help
output, which is imho what most sane programmers want (also works with optional arguments):Official docs on this: https://docs.python.org/3/library/argparse.html#choices
The best way to do this is by using python inbuilt module add_mutually_exclusive_group.
If you want only one argument to be selected by command line just use required=True as an argument for group
Requirements Review
argparse
(I will ignore this one)There are also some implicit requirements when living on command line:
Sample solution using
docopt
(filemanagelog.py
):Try to run it:
Show the help:
And use it:
Short alternative
short.py
There can be even shorter variant:
Usage looks like this:
Note, that instead of boolean values for "process" and "upload" keys there are counters.
It turns out, we cannot prevent duplication of these words:
Conclusions
Designing good command line interface can be challenging sometime.
There are multiple aspects of command line based program:
argparse
offers a lot, but restricts possible scenarios and can become very complex.With
docopt
things go much shorter while preserving readability and offering high degree of flexibility. If you manage getting parsed arguments from dictionary and do some of conversions (to integer, opening files..) manually (or by other library calledschema
), you may finddocopt
good fit for command line parsing.I know this is old as dirt, but the way to require one option but forbid more than one (XOR) is like this:
Output: