Skip to content

Commit f97c59a

Browse files
committed
#10424: argument names are now included in the missing argument message
Fix and initial test patch by Michele Orrù.
1 parent 8dd8d58 commit f97c59a

File tree

3 files changed

+69
-10
lines changed

3 files changed

+69
-10
lines changed

Lib/argparse.py

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1969,17 +1969,12 @@ def consume_positionals(start_index):
19691969
# if we didn't consume all the argument strings, there were extras
19701970
extras.extend(arg_strings[stop_index:])
19711971

1972-
# if we didn't use all the Positional objects, there were too few
1973-
# arg strings supplied.
1974-
if positionals:
1975-
self.error(_('too few arguments'))
1976-
19771972
# make sure all required actions were present
1978-
for action in self._actions:
1979-
if action.required:
1980-
if action not in seen_actions:
1981-
name = _get_action_name(action)
1982-
self.error(_('argument %s is required') % name)
1973+
required_actions = [_get_action_name(action) for action in self._actions
1974+
if action.required and action not in seen_actions]
1975+
if required_actions:
1976+
self.error(_('the following arguments are required: %s') %
1977+
', '.join(required_actions))
19831978

19841979
# make sure all required groups had one option present
19851980
for group in self._mutually_exclusive_groups:

Lib/test/test_argparse.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4480,6 +4480,67 @@ def spam(string):
44804480
else:
44814481
self.fail()
44824482

4483+
# =========================
4484+
# MessageContentError tests
4485+
# =========================
4486+
4487+
class TestMessageContentError(TestCase):
4488+
4489+
def test_missing_argument_name_in_message(self):
4490+
parser = ErrorRaisingArgumentParser(prog='PROG', usage='')
4491+
parser.add_argument('req_pos', type=str)
4492+
parser.add_argument('-req_opt', type=int, required=True)
4493+
parser.add_argument('need_one', type=str, nargs='+')
4494+
4495+
with self.assertRaises(ArgumentParserError) as cm:
4496+
parser.parse_args([])
4497+
msg = str(cm.exception)
4498+
self.assertRegex(msg, 'req_pos')
4499+
self.assertRegex(msg, 'req_opt')
4500+
self.assertRegex(msg, 'need_one')
4501+
with self.assertRaises(ArgumentParserError) as cm:
4502+
parser.parse_args(['myXargument'])
4503+
msg = str(cm.exception)
4504+
self.assertNotIn(msg, 'req_pos')
4505+
self.assertRegex(msg, 'req_opt')
4506+
self.assertRegex(msg, 'need_one')
4507+
with self.assertRaises(ArgumentParserError) as cm:
4508+
parser.parse_args(['myXargument', '-req_opt=1'])
4509+
msg = str(cm.exception)
4510+
self.assertNotIn(msg, 'req_pos')
4511+
self.assertNotIn(msg, 'req_opt')
4512+
self.assertRegex(msg, 'need_one')
4513+
4514+
def test_optional_optional_not_in_message(self):
4515+
parser = ErrorRaisingArgumentParser(prog='PROG', usage='')
4516+
parser.add_argument('req_pos', type=str)
4517+
parser.add_argument('--req_opt', type=int, required=True)
4518+
parser.add_argument('--opt_opt', type=bool, nargs='?',
4519+
default=True)
4520+
with self.assertRaises(ArgumentParserError) as cm:
4521+
parser.parse_args([])
4522+
msg = str(cm.exception)
4523+
self.assertRegex(msg, 'req_pos')
4524+
self.assertRegex(msg, 'req_opt')
4525+
self.assertNotIn(msg, 'opt_opt')
4526+
with self.assertRaises(ArgumentParserError) as cm:
4527+
parser.parse_args(['--req_opt=1'])
4528+
msg = str(cm.exception)
4529+
self.assertRegex(msg, 'req_pos')
4530+
self.assertNotIn(msg, 'req_opt')
4531+
self.assertNotIn(msg, 'opt_opt')
4532+
4533+
def test_optional_positional_not_in_message(self):
4534+
parser = ErrorRaisingArgumentParser(prog='PROG', usage='')
4535+
parser.add_argument('req_pos')
4536+
parser.add_argument('optional_positional', nargs='?', default='eggs')
4537+
with self.assertRaises(ArgumentParserError) as cm:
4538+
parser.parse_args([])
4539+
msg = str(cm.exception)
4540+
self.assertRegex(msg, 'req_pos')
4541+
self.assertNotIn(msg, 'optional_positional')
4542+
4543+
44834544
# ======================
44844545
# parse_known_args tests
44854546
# ======================

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,9 @@ Core and Builtins
187187
Library
188188
-------
189189

190+
- Issue #10424: Argparse now includes the names of the missing required
191+
arguments in the missing arguments error message.
192+
190193
- Issue #12168: SysLogHandler now allows NUL termination to be controlled using
191194
a new 'append_nul' attribute on the handler.
192195

0 commit comments

Comments
 (0)