[Python-checkins] bpo-26510: make argparse subparsers required by default (#3027)
Éric Araujo
webhook-mailer at python.org
Wed Sep 20 17:35:30 EDT 2017
https://github.com/python/cpython/commit/aaf6fc0982c916cb71d9e0afcd7dda4ba495793b
commit: aaf6fc0982c916cb71d9e0afcd7dda4ba495793b
branch: master
author: Anthony Sottile <asottile at umich.edu>
committer: Éric Araujo <merwok at users.noreply.github.com>
date: 2017-09-20T17:35:27-04:00
summary:
bpo-26510: make argparse subparsers required by default (#3027)
This fixes a regression from Python 2. To get optional subparsers,
use the new parameter ``add_subparsers(required=False)``.
Patch by Anthony Sottile.
files:
A Misc/NEWS.d/next/Library/2017-09-19-13-29-29.bpo-26510.oncW6V.rst
M Doc/library/argparse.rst
M Lib/argparse.py
M Lib/test/test_argparse.py
diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst
index c425be6d481..53e670161dd 100644
--- a/Doc/library/argparse.rst
+++ b/Doc/library/argparse.rst
@@ -1539,8 +1539,8 @@ Sub-commands
.. method:: ArgumentParser.add_subparsers([title], [description], [prog], \
[parser_class], [action], \
- [option_string], [dest], [help], \
- [metavar])
+ [option_string], [dest], [required] \
+ [help], [metavar])
Many programs split up their functionality into a number of sub-commands,
for example, the ``svn`` program can invoke sub-commands like ``svn
@@ -1576,6 +1576,9 @@ Sub-commands
* dest_ - name of the attribute under which sub-command name will be
stored; by default ``None`` and no value is stored
+ * required_ - Whether or not a subcommand must be provided, by default
+ ``True``.
+
* help_ - help for sub-parser group in help output, by default ``None``
* metavar_ - string presenting available sub-commands in help; by default it
diff --git a/Lib/argparse.py b/Lib/argparse.py
index d59e645203c..98bbed0e508 100644
--- a/Lib/argparse.py
+++ b/Lib/argparse.py
@@ -1066,6 +1066,7 @@ def __init__(self,
prog,
parser_class,
dest=SUPPRESS,
+ required=True,
help=None,
metavar=None):
@@ -1079,6 +1080,7 @@ def __init__(self,
dest=dest,
nargs=PARSER,
choices=self._name_parser_map,
+ required=required,
help=help,
metavar=metavar)
diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py
index d8bcd7309d2..c4440e4df7c 100644
--- a/Lib/test/test_argparse.py
+++ b/Lib/test/test_argparse.py
@@ -1807,7 +1807,7 @@ def _get_parser(self, subparser_help=False, prefix_chars=None,
'bar', type=float, help='bar help')
# check that only one subparsers argument can be added
- subparsers_kwargs = {}
+ subparsers_kwargs = {'required': False}
if aliases:
subparsers_kwargs['metavar'] = 'COMMAND'
subparsers_kwargs['title'] = 'commands'
@@ -1907,6 +1907,41 @@ def test_dest(self):
self.assertEqual(NS(foo=False, bar='1', baz='2'),
parser.parse_args('1 2'.split()))
+ def _test_required_subparsers(self, parser):
+ # Should parse the sub command
+ ret = parser.parse_args(['run'])
+ self.assertEqual(ret.command, 'run')
+
+ # Error when the command is missing
+ self.assertArgumentParserError(parser.parse_args, ())
+
+ def test_required_subparsers_via_attribute(self):
+ parser = ErrorRaisingArgumentParser()
+ subparsers = parser.add_subparsers(dest='command')
+ subparsers.required = True
+ subparsers.add_parser('run')
+ self._test_required_subparsers(parser)
+
+ def test_required_subparsers_via_kwarg(self):
+ parser = ErrorRaisingArgumentParser()
+ subparsers = parser.add_subparsers(dest='command', required=True)
+ subparsers.add_parser('run')
+ self._test_required_subparsers(parser)
+
+ def test_required_subparsers_default(self):
+ parser = ErrorRaisingArgumentParser()
+ subparsers = parser.add_subparsers(dest='command')
+ subparsers.add_parser('run')
+ self._test_required_subparsers(parser)
+
+ def test_optional_subparsers(self):
+ parser = ErrorRaisingArgumentParser()
+ subparsers = parser.add_subparsers(dest='command', required=False)
+ subparsers.add_parser('run')
+ # No error here
+ ret = parser.parse_args(())
+ self.assertIsNone(ret.command)
+
def test_help(self):
self.assertEqual(self.parser.format_usage(),
'usage: PROG [-h] [--foo] bar {1,2,3} ...\n')
diff --git a/Misc/NEWS.d/next/Library/2017-09-19-13-29-29.bpo-26510.oncW6V.rst b/Misc/NEWS.d/next/Library/2017-09-19-13-29-29.bpo-26510.oncW6V.rst
new file mode 100644
index 00000000000..26a6b4b0ee8
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2017-09-19-13-29-29.bpo-26510.oncW6V.rst
@@ -0,0 +1,3 @@
+argparse subparsers are now required by default. This matches behaviour in Python 2.
+For optional subparsers, use the new parameter ``add_subparsers(required=False)``.
+Patch by Anthony Sottile.
More information about the Python-checkins
mailing list