How to parse several positional arguments with nargs='+'
<p>Here's a short summary of what I am trying to achieve: </p>

<ul>
<li>Get one or more (tabular) files</li>
<li>Look for a particular string key (at the moment there's just a single key, but I can imagine expanding this to take in multiple keys)</li>
<li>The rows that match the key, extract the character(s) at a given position, or range of positions. </li>
</ul>

<p>So in an ideal world I'd like to run my script in the following ways, they are all valid use cases:</p>

<pre><code>python myscript.py file1 file2 file3 "key" 10
python myscript.py file1 file2 "key" 10 12
python myscript.py file1 "key" 10 12
python myscript.py file1 "key" 10
</code></pre>

<p>Given the use case I tried:</p>

<pre><code>parser = argparse.ArgumentParser()
parser.add_argument("files", nargs='+', help="input files")
parser.add_argument("gene", help="gene of interest")
parser.add_argument("pos", nargs='+', type=int, help="position(s) to analyze")

""" Validate pos """
if len(args.pos) &gt; 2:
    sys.exit("Positions argument needs to be a single integer or two integers denoting a range!")

...

# in some other function
if len(args.pos) == 1:
    key = row[SIND][args.pos[0]]
elif len(args.pos) == 2:
    key = row[SIND][args.pos[0] : args.pos[1]]
else:
    print(args.pos, len(args.pos))
    sys.exit("args.pos assertion failed!")
</code></pre>

<p>It works when there is only one integer but not when I send two integers to analyze a range instead. In the latter case the "key" is interpreted as a file as well thus I get <code>FileNotFoundError: [Errno 2] No such file or directory: 'IGHV4-39'</code>.</p>

<p><strong>Question1:</strong> Is it possible to flag or indicate positional arguments, so that I can tell argparse when the <code>files</code> parameter ends and <code>gene</code> starts? I don't want to make them optional arguments, since the logic of the script is incomplete if either of the three parameters is omitted. </p>

<p><strong>Question2:</strong> Is it otherwise helpful to divide the pos parameter into two; pos which takes a single integer, and range which takes two integers, then make them somehow exclusive? </p>

<p>Any ideas?</p>