[3.13] gh-72795: Make positional arguments with nargs='*' or REMAINDER non-required (GH-124306) (#124421)

This allows to use positional argument with nargs='*' and without default
in mutually exclusive group and improves error message about required
arguments.
(cherry picked from commit 3c83f9958c)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
This commit is contained in:
Miss Islington (bot) 2024-10-08 00:51:35 +02:00 committed by GitHub
parent db3ccd8b62
commit 0a046771c0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 32 additions and 8 deletions

View file

@ -1561,9 +1561,8 @@ class _ActionsContainer(object):
# mark positional arguments as required if at least one is # mark positional arguments as required if at least one is
# always required # always required
if kwargs.get('nargs') not in [OPTIONAL, ZERO_OR_MORE]: nargs = kwargs.get('nargs')
kwargs['required'] = True if nargs not in [OPTIONAL, ZERO_OR_MORE, REMAINDER, SUPPRESS, 0]:
if kwargs.get('nargs') == ZERO_OR_MORE and 'default' not in kwargs:
kwargs['required'] = True kwargs['required'] = True
# return the keyword arguments with no option strings # return the keyword arguments with no option strings

View file

@ -3201,7 +3201,7 @@ class TestMutuallyExclusiveOptionalAndPositional(MEMixin, TestCase):
group = parser.add_mutually_exclusive_group(required=required) group = parser.add_mutually_exclusive_group(required=required)
group.add_argument('--foo', action='store_true', help='FOO') group.add_argument('--foo', action='store_true', help='FOO')
group.add_argument('--spam', help='SPAM') group.add_argument('--spam', help='SPAM')
group.add_argument('badger', nargs='*', default='X', help='BADGER') group.add_argument('badger', nargs='*', help='BADGER')
return parser return parser
failures = [ failures = [
@ -3212,13 +3212,13 @@ class TestMutuallyExclusiveOptionalAndPositional(MEMixin, TestCase):
'--foo X Y', '--foo X Y',
] ]
successes = [ successes = [
('--foo', NS(foo=True, spam=None, badger='X')), ('--foo', NS(foo=True, spam=None, badger=[])),
('--spam S', NS(foo=False, spam='S', badger='X')), ('--spam S', NS(foo=False, spam='S', badger=[])),
('X', NS(foo=False, spam=None, badger=['X'])), ('X', NS(foo=False, spam=None, badger=['X'])),
('X Y Z', NS(foo=False, spam=None, badger=['X', 'Y', 'Z'])), ('X Y Z', NS(foo=False, spam=None, badger=['X', 'Y', 'Z'])),
] ]
successes_when_not_required = [ successes_when_not_required = [
('', NS(foo=False, spam=None, badger='X')), ('', NS(foo=False, spam=None, badger=[])),
] ]
usage_when_not_required = '''\ usage_when_not_required = '''\
@ -6491,7 +6491,28 @@ class TestExitOnError(TestCase):
self.parser.add_argument('bar') self.parser.add_argument('bar')
self.parser.add_argument('baz') self.parser.add_argument('baz')
self.assertRaisesRegex(argparse.ArgumentError, 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, []) self.parser.parse_args, [])
def test_required_mutually_exclusive_args(self): def test_required_mutually_exclusive_args(self):

View file

@ -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.