Parameters starting with - or -- are usually considered optional. All other parameters are positional parameters and as such required by design (like positional function arguments). It is possible to require optional arguments, but this is a bit against their design. Since they are still part of the non-positional arguments, they will still be listed under the confusing header “optional arguments” even if they are required. The missing square brackets in the usage part however show that they are indeed required.
See also the documentation:
In general, the argparse module assumes that flags like -f and --bar indicate optional arguments, which can always be omitted at the command line.
Note: Required options are generally considered bad form because users expect options to be optional, and thus they should be avoided when possible.
That being said, the headers “positional arguments” and “optional arguments” in the help are generated by two argument groups in which the arguments are automatically separated into. Now, you could “hack into it” and change the name of the optional ones, but a far more elegant solution would be to create another group for “required named arguments” (or whatever you want to call them):
parser = argparse.ArgumentParser(description='Foo')
parser.add_argument('-o', '--output', help='Output file name', default='stdout')
requiredNamed = parser.add_argument_group('required named arguments')
requiredNamed.add_argument('-i', '--input', help='Input file name', required=True)
parser.parse_args(['-h'])
usage: [-h] [-o OUTPUT] -i INPUT
Foo
optional arguments:
-h, --help show this help message and exit
-o OUTPUT, --output OUTPUT
Output file name
required named arguments:
-i INPUT, --input INPUT
Input file name
Answer from poke on Stack OverflowParameters starting with - or -- are usually considered optional. All other parameters are positional parameters and as such required by design (like positional function arguments). It is possible to require optional arguments, but this is a bit against their design. Since they are still part of the non-positional arguments, they will still be listed under the confusing header “optional arguments” even if they are required. The missing square brackets in the usage part however show that they are indeed required.
See also the documentation:
In general, the argparse module assumes that flags like -f and --bar indicate optional arguments, which can always be omitted at the command line.
Note: Required options are generally considered bad form because users expect options to be optional, and thus they should be avoided when possible.
That being said, the headers “positional arguments” and “optional arguments” in the help are generated by two argument groups in which the arguments are automatically separated into. Now, you could “hack into it” and change the name of the optional ones, but a far more elegant solution would be to create another group for “required named arguments” (or whatever you want to call them):
parser = argparse.ArgumentParser(description='Foo')
parser.add_argument('-o', '--output', help='Output file name', default='stdout')
requiredNamed = parser.add_argument_group('required named arguments')
requiredNamed.add_argument('-i', '--input', help='Input file name', required=True)
parser.parse_args(['-h'])
usage: [-h] [-o OUTPUT] -i INPUT
Foo
optional arguments:
-h, --help show this help message and exit
-o OUTPUT, --output OUTPUT
Output file name
required named arguments:
-i INPUT, --input INPUT
Input file name
Since I prefer to list required arguments before optional, I hack around it via:
parser = argparse.ArgumentParser()
parser._action_groups.pop()
required = parser.add_argument_group('required arguments')
optional = parser.add_argument_group('optional arguments')
required.add_argument('--required_arg', required=True)
optional.add_argument('--optional_arg')
return parser.parse_args()
and this outputs:
usage: main.py [-h] --required_arg REQUIRED_ARG [--optional_arg OPTIONAL_ARG]
required arguments:
--required_arg REQUIRED_ARG
optional arguments:
--optional_arg OPTIONAL_ARG
I can live without -h, --help showing up in the optional arguments group.
python - Is it better practice to set default values for optional argparse arguments? - Software Engineering Stack Exchange
How to set several required arguments into an optional group?
ArgParse Optional Command Line Arguments?
Argparse complains argument required when default is provided
Videos
The premise behind your question is mistaken.
>>> import argparse
>>> p = argparse.ArgumentParser()
>>> p.add_argument('-a')
>>> p.parse_args()
Namespace(a=None)
The -a argument is already optional by default (you don't need required=False), and its default is already None, ensuring that args.a exists without any manual intervention.
You have to opt-in to having no default at all.
>>> p.add_argument("-b", default=argparse.SUPPRESS)
>>> p.parse_args()
Namespace(a=None)
So yes, it probably is a good idea to have some default, and argparse acknowledges that by providing one.
So some clarifications here. To answer this question for python specifically, argparse does in fact default optional argument values to None. Your problem arises from having multiple subcommands that take different arguments, but go through the same code flow. If you pass the same args from subcommands a, b, c that have different options, then you do have to handle each option that is not common across all three. In that workflow, I would recommend backfilling each option that is not guaranteed to exist.
import argparse
import datetime
today = datetime.datetime.today()
file_date = today - datetime.timedelta(days = 2)
parser = argparse.ArgumentParser()
parser.add_argument("--start_date")
args = parser.parse_args()I want to run my python script with the option to add a start_date argument. If start date is not specified then the date will be file_date by default.
I'm a little confused how argparse is working here though. I can run my file "python test_argparse.py" fine. But when I enter:
python test_argparse.py --start_date = 01/05/2017
I get:
error: unrecognized arguments: 01/05/2017
Before I look at setting the default argument as file_date, how do I call the optional start_date argument in the command line? I'm sure I'm missing something simple here.