https://github.com/python/cpython/commit/3c83f9958c14cd62ad8951c53536f7788745b0ba
commit: 3c83f9958c14cd62ad8951c53536f7788745b0ba
branch: main
author: Serhiy Storchaka <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2024-09-24T07:55:33Z
summary:
gh-72795: Make positional arguments with nargs='*' or REMAINDER non-required
(GH-124306)
This allows to use positional argument with nargs='*' and without default
in mutually exclusive group and improves error message about required
arguments.
files:
A Misc/NEWS.d/next/Library/2024-09-21-22-32-21.gh-issue-72795.naLmkX.rst
M Lib/argparse.py
M Lib/test/test_argparse.py
diff --git a/Lib/argparse.py b/Lib/argparse.py
index 89496cbe454e09..3974ebedabe6f4 100644
--- a/Lib/argparse.py
+++ b/Lib/argparse.py
@@ -1532,9 +1532,8 @@ def _get_positional_kwargs(self, dest, **kwargs):
# mark positional arguments as required if at least one is
# always required
- if kwargs.get('nargs') not in [OPTIONAL, ZERO_OR_MORE]:
- kwargs['required'] = True
- if kwargs.get('nargs') == ZERO_OR_MORE and 'default' not in kwargs:
+ nargs = kwargs.get('nargs')
+ if nargs not in [OPTIONAL, ZERO_OR_MORE, REMAINDER, SUPPRESS, 0]:
kwargs['required'] = True
# return the keyword arguments with no option strings
diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py
index 3d43fc82d20614..b04f044f5e2580 100644
--- a/Lib/test/test_argparse.py
+++ b/Lib/test/test_argparse.py
@@ -3079,7 +3079,7 @@ def get_parser(self, required):
group = parser.add_mutually_exclusive_group(required=required)
group.add_argument('--foo', action='store_true', help='FOO')
group.add_argument('--spam', help='SPAM')
- group.add_argument('badger', nargs='*', default='X', help='BADGER')
+ group.add_argument('badger', nargs='*', help='BADGER')
return parser
failures = [
@@ -3090,13 +3090,13 @@ def get_parser(self, required):
'--foo X Y',
]
successes = [
- ('--foo', NS(foo=True, spam=None, badger='X')),
- ('--spam S', NS(foo=False, spam='S', badger='X')),
+ ('--foo', NS(foo=True, spam=None, badger=[])),
+ ('--spam S', NS(foo=False, spam='S', badger=[])),
('X', NS(foo=False, spam=None, badger=['X'])),
('X Y Z', NS(foo=False, spam=None, badger=['X', 'Y', 'Z'])),
]
successes_when_not_required = [
- ('', NS(foo=False, spam=None, badger='X')),
+ ('', NS(foo=False, spam=None, badger=[])),
]
usage_when_not_required = '''\
@@ -6369,7 +6369,28 @@ def test_required_args(self):
self.parser.add_argument('bar')
self.parser.add_argument('baz')
self.assertRaisesRegex(argparse.ArgumentError,
- 'the following arguments are required: bar,
baz',
+ 'the following arguments are required: bar,
baz$',
+ self.parser.parse_args, [])
+
+ def test_required_args_optional(self):
+ self.parser.add_argument('bar')
+ self.parser.add_argument('baz', nargs='?')
+ self.assertRaisesRegex(argparse.ArgumentError,
+ 'the following arguments are required: bar$',
+ self.parser.parse_args, [])
+
+ def test_required_args_zero_or_more(self):
+ self.parser.add_argument('bar')
+ self.parser.add_argument('baz', nargs='*')
+ self.assertRaisesRegex(argparse.ArgumentError,
+ 'the following arguments are required: bar$',
+ self.parser.parse_args, [])
+
+ def test_required_args_remainder(self):
+ self.parser.add_argument('bar')
+ self.parser.add_argument('baz', nargs='...')
+ self.assertRaisesRegex(argparse.ArgumentError,
+ 'the following arguments are required: bar$',
self.parser.parse_args, [])
def test_required_mutually_exclusive_args(self):
diff --git
a/Misc/NEWS.d/next/Library/2024-09-21-22-32-21.gh-issue-72795.naLmkX.rst
b/Misc/NEWS.d/next/Library/2024-09-21-22-32-21.gh-issue-72795.naLmkX.rst
new file mode 100644
index 00000000000000..15c0918097367f
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-09-21-22-32-21.gh-issue-72795.naLmkX.rst
@@ -0,0 +1,4 @@
+Positional arguments with :ref:`nargs` equal to ``'*'`` or
+:data:`!argparse.REMAINDER` are no longer required. This allows to use
+positional argument with ``nargs='*'`` and without ``default`` in mutually
+exclusive group and improves error message about required arguments.
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]