In an ipython
session:
In [1]: import argparse
In [2]: p = argparse.ArgumentParser()
In [3]: p.add_argument('A');
In [4]: p.add_argument('B');
In [5]: p.add_argument('C', nargs='?'); # optional positional
In [6]: p.print_help()
usage: ipython3 [-h] A B [C]
positional arguments:
A
B
C
optional arguments:
-h, --help show this help message and exit
If only 2 are given, the last is default None
:
In [7]: p.parse_args('foo bar'.split())
Out[7]: Namespace(A='foo', B='bar', C=None)
In [8]: p.parse_args('foo bar baz'.split())
Out[8]: Namespace(A='foo', B='bar', C='baz')
We can test args.A
and raise an error is C
is not given (its default):
In [9]: args = p.parse_args('A bar baz'.split())
In [10]: if args.A == 'A' and args.C is None:
...: p.error('C is required')
...:
In [11]: args = p.parse_args('A bar'.split())
In [12]: if args.A == 'A' and args.C is None:
...: p.error('C is required')
...:
usage: ipython3 [-h] A B [C]
ipython3: error: C is required
We could do something similar with optionals/flagged
arguments.
While it's possible to do the required
testing with a 2 stage parser, I think testing after parsing is simpler.
===
In [16]: p = argparse.ArgumentParser()
In [17]: p.add_argument('--A', required=True);
In [18]: p.add_argument('--B', required=True);
In [19]: p.add_argument('--C');
In [20]: p.print_help()
usage: ipython3 [-h] --A A --B B [--C C]
optional arguments:
-h, --help show this help message and exit
--A A
--B B
--C C
In [21]: args = p.parse_args('--A foo --B bar'.split())
In [22]: args
Out[22]: Namespace(A='foo', B='bar', C=None)