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.
This commit is contained in:
parent
c578271366
commit
3c83f9958c
@ -1532,9 +1532,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
|
||||||
|
@ -3079,7 +3079,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 = [
|
||||||
@ -3090,13 +3090,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 = '''\
|
||||||
@ -6369,7 +6369,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):
|
||||||
|
@ -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.
|
Loading…
x
Reference in New Issue
Block a user