The surest way of identifying whether the user has provided a value is to leave the default at the default None
. There's nothing the user can say that will produce the same thing. Then after parsing all you need to do is:
if args.myval is None:
# no user input, set my own special default
else:
# user value
If you set the default=argparse.SUPPRESS
, the attribute will be omitted from the args
namespace. But testing for that case it a bit more awkward.
args.myval
will raise an error, which you could catch. Or you could use hasattr(args, 'myval'). Or handle the missing key in
vars(args)`.
Internally parse_args
maintains a list (set
actually) of Actions that it has 'seen'. That's used to test for required Actions. But that isn't available to users. If it were available, sophisticated users could perform a wider variety of co-occurrence tests.
In [28]: import argparse
In [29]: parser = argparse.ArgumentParser()
In [30]: a1 = parser.add_argument('-f','--foo')
Test without a value:
In [31]: args = parser.parse_args([])
In [32]: args
Out[32]: Namespace(foo=None) # foo is present
In [33]: args.foo is None
Out[33]: True
Change the default to SUPPRESS
:
In [35]: a1.default = argparse.SUPPRESS
In [36]: args = parser.parse_args([])
In [37]: args
Out[37]: Namespace() # foo is missing
In [38]: args.foo
AttributeError: 'Namespace' object has no attribute 'foo'
We could put args.foo
in a try: except AttributeError
block.
In [39]: hasattr(args, 'foo')
Out[39]: False
Or dictionary testing for missing value
In [46]: vars(args)
Out[46]: {}
In [47]: vars(args).get('foo') is None
Out[47]: True
In [48]: 'foo' in vars(args)
Out[48]: False
A default is most useful when it provides a valid, useful value, and it saves you from extra testing after parsing.