I'm using python 3.74 and I'm trying to use the argparse module to read a pair of numbers into the variable nums
. I would like to check if certain conditions hold between the two numbers and then sort them.
I have the code below.
import argparse
def f(x):
assert x[0]!=x[1],"err"
return sorted([int(y) for y in x])
parser = argparse.ArgumentParser()
parser.add_argument("--nums", required=True, type=f,nargs=2)
args = parser.parse_args()
I want the snippet above to return [1, 2]
when the input is 2 1
. I get an IndexError instead.
This led me to investigate with the code below:
parser = argparse.ArgumentParser()
parser.add_argument("--nums", required=True, type=lambda x:x*2 ,nargs=2)
args = parser.parse_args()
now the output for 2 1
is ['22', '11']
which leads me to believe that type is applied te each of the values separately. Is there any way to perform type validation on --nums as a whole? I'd preferably like to do it within add_argument.
As the documentation states
type=
can take any callable that takes a single string argument and returns the converted value
And we can confirm this by looking at the ArgParse implementation, nargs
arguments are evaluated individually. So your f
function is being called for each argument.
If you really want it to be done as part of the type checking, you could require a string input of 1,2
and parse that yourself like so:
def f(x):
x = x.split(',')
assert x[0]!=x[1],'err'
return sorted([int(y) for y in x])
Where an input of 1,2
results in [1, 2]
But that defeats the purpose of argparse, so you're better off simply calling your validator after the arguments have been parsed, the experience for the end-user is no different.
parser.add_argument("--nums", required=True, type=int, nargs=2)
args = parser.parse_args()
print(f(args.nums))
An input of 2 1
returns [1, 2]