Python Argparse: how to make an argument required if and only if one flag is given?
<p>I am wondering how can I make one argument required when one flag is given, and optional when that flag is not given?</p>

<pre><code>import argparse


parser = argparse.ArgumentParser()

parser.add_argument('-c', '--convert', action = 'store_true')
parser.add_argument('-l', '--lookup', action = 'store_true')
parser.add_argument('name', type = str) 

args = parser.parse_args()

if args.name:
    print(args.name)
if args.convert:
    print ("convert now!")
</code></pre>

<p>For example, in the codes above, I want <code>name</code> to be required, only when <code>-c</code> is given. When I run the program only with <code>-l</code>, then there is an error:</p>

<pre><code>$ python3 test.py -l
usage: test.py [-h] [-c] [-l] name
test.py: error: the following arguments are required: name
</code></pre>

<p>I have tried to use argument group to divide the arguments into two groups 1. <code>-c</code> and <code>name</code>; 2. <code>-l</code>, but it didn't really work.</p>

<p>Any suggestions are appreciated!</p>

<p>There isn't anything in <code>argparse</code> to do this directly; but it can be approximated in various ways</p>

<pre><code>parser.add_argument('-c', '--convert', action = 'store_true')
parser.add_argument('-l', '--lookup', action = 'store_true')
parser.add_argument('name', nargs='?', default='good default') 
</code></pre>

<p>It's not required in either case, but in the case of <code>-c</code> you could either use the <code>good default</code>, or you can complain after parsing.</p>

<pre><code>parser.add_argument('-c', '--convert')
parser.add_argument('-l', '--lookup', nargs='?', default='adefault', const='aconst')
</code></pre>

<p>In this case, <code>-c</code> expects an argument, your required <code>name</code>.  An argument is optional for <code>-l</code>.  If no <code>-l</code>, the value is the <code>default</code>; if  <code>-l</code> without the argument, the value is the <code>const</code>.  You could even put <code>-c</code> and <code>-l</code> in a mutually exclusive group.</p>

<p>There isn't a mechanism for requiring several arguments to go together (i.e. no 'mutually-required-group`).  However subparsers work along that line.  Do I need to illustrate how subparsers could be use here?</p>

<p>Custom Actions classes can be used to force some sort of interaction between arguments, but usually it's easier to implement that sort of thing after parsing.  Remember <code>argparse</code> allows you give arguments in any order.  Thus the <code>name</code>  positional could occur before <code>-c</code>, or after, or between <code>-l</code> and <code>-c</code> etc.</p>

python python-3.x arguments argparse