argparse with required subcommands
Question:
With python’s argparse, how do I make a subcommand a required argument? I want to do this because I want argparse to error out if a subcommand is not specified. I override the error method to print help instead. I have 3-deep nested subcommands, so it’s not a matter of simply handling zero arguments at the top level.
In the following example, if this is called like so, I get:
$./simple.py
$
What I want it to do instead is for argparse to complain that the required subcommand was not specified:
import argparse
class MyArgumentParser(argparse.ArgumentParser):
def error(self, message):
self.print_help(sys.stderr)
self.exit(0, '%s: error: %sn' % (self.prog, message))
def main():
parser = MyArgumentParser(description='Simple example')
subs = parser.add_subparsers()
sub_one = subs.add_parser('one', help='does something')
sub_two = subs.add_parser('two', help='does something else')
parser.parse_args()
if __name__ == '__main__':
main()
Answers:
How about using required=True
? More info here.
You can use the dest
argument, which is documented in the last example in the documentation for add_subparsers()
:
# required_subparser.py
import argparse
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest='subparser_name')
one = subparsers.add_parser('one')
two = subparsers.add_parser('two')
args = parser.parse_args()
Running with Python 2.7:
$python required_subparser.py
usage: required_subparser.py [-h] {one,two} ...
required_subparser.py: error: too few arguments
$python required_subparser.py one
$# no error
There was a change in 3.3 in the error message for required arguments, and subcommands got lost in the dust.
http://bugs.python.org/issue9253#msg186387
There I suggest this work around, setting the required
attribute after the subparsers
is defined.
parser = ArgumentParser(prog='test')
subparsers = parser.add_subparsers()
subparsers.required = True
subparsers.dest = 'command'
subparser = subparsers.add_parser("foo", help="run foo")
parser.parse_args()
update
A related pull-request: https://github.com/python/cpython/pull/3027
In addition to hpaulj’s answer: you can also use the required
keyword argument with ArgumentParser.add_subparsers()
since Python 3.7. You also need to pass dest
as argument. Otherwise you will get an error: TypeError: sequence item 0: expected str instance, NoneType found
.
Example file example.py
:
import argparse
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest='command', required=True)
foo_parser = subparsers.add_parser("foo", help="command foo")
args = parser.parse_args()
Output of the call without an argument:
$ python example.py
usage: example.py [-h] {foo} ...
example.py: error: the following arguments are required: command
With python’s argparse, how do I make a subcommand a required argument? I want to do this because I want argparse to error out if a subcommand is not specified. I override the error method to print help instead. I have 3-deep nested subcommands, so it’s not a matter of simply handling zero arguments at the top level.
In the following example, if this is called like so, I get:
$./simple.py
$
What I want it to do instead is for argparse to complain that the required subcommand was not specified:
import argparse
class MyArgumentParser(argparse.ArgumentParser):
def error(self, message):
self.print_help(sys.stderr)
self.exit(0, '%s: error: %sn' % (self.prog, message))
def main():
parser = MyArgumentParser(description='Simple example')
subs = parser.add_subparsers()
sub_one = subs.add_parser('one', help='does something')
sub_two = subs.add_parser('two', help='does something else')
parser.parse_args()
if __name__ == '__main__':
main()
How about using required=True
? More info here.
You can use the dest
argument, which is documented in the last example in the documentation for add_subparsers()
:
# required_subparser.py
import argparse
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest='subparser_name')
one = subparsers.add_parser('one')
two = subparsers.add_parser('two')
args = parser.parse_args()
Running with Python 2.7:
$python required_subparser.py
usage: required_subparser.py [-h] {one,two} ...
required_subparser.py: error: too few arguments
$python required_subparser.py one
$# no error
There was a change in 3.3 in the error message for required arguments, and subcommands got lost in the dust.
http://bugs.python.org/issue9253#msg186387
There I suggest this work around, setting the required
attribute after the subparsers
is defined.
parser = ArgumentParser(prog='test')
subparsers = parser.add_subparsers()
subparsers.required = True
subparsers.dest = 'command'
subparser = subparsers.add_parser("foo", help="run foo")
parser.parse_args()
update
A related pull-request: https://github.com/python/cpython/pull/3027
In addition to hpaulj’s answer: you can also use the required
keyword argument with ArgumentParser.add_subparsers()
since Python 3.7. You also need to pass dest
as argument. Otherwise you will get an error: TypeError: sequence item 0: expected str instance, NoneType found
.
Example file example.py
:
import argparse
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest='command', required=True)
foo_parser = subparsers.add_parser("foo", help="command foo")
args = parser.parse_args()
Output of the call without an argument:
$ python example.py
usage: example.py [-h] {foo} ...
example.py: error: the following arguments are required: command