Skip to content

Commit

Permalink
pythongh-53834: Fix support of arguments with choices in argparse
Browse files Browse the repository at this point in the history
Positional arguments with nargs equal to '?' or '*' no longer check
default against choices.
Optional arguments with nargs equal to '?' no longer check const
against choices.
  • Loading branch information
serhiy-storchaka committed Sep 25, 2024
1 parent 4a5e4aa commit 794740c
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 13 deletions.
6 changes: 1 addition & 5 deletions Lib/argparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -2485,19 +2485,15 @@ def _get_values(self, action, arg_strings):
value = action.default
if isinstance(value, str):
value = self._get_value(action, value)
self._check_value(action, value)

# when nargs='*' on a positional, if there were no command-line
# args, use the default if it is anything other than None
elif (not arg_strings and action.nargs == ZERO_OR_MORE and
not action.option_strings):
if action.default is not None:
value = action.default
self._check_value(action, value)
else:
# since arg_strings is always [] at this point
# there is no need to use self._check_value(action, value)
value = arg_strings
value = []

# single argument or optional argument produces a single value
elif len(arg_strings) == 1 and action.nargs in [None, OPTIONAL]:
Expand Down
16 changes: 8 additions & 8 deletions Lib/test/test_argparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -621,9 +621,9 @@ class TestOptionalsNargsOptional(ParserTestCase):
Sig('-w', nargs='?'),
Sig('-x', nargs='?', const=42),
Sig('-y', nargs='?', default='spam'),
Sig('-z', nargs='?', type=int, const='42', default='84'),
Sig('-z', nargs='?', type=int, const='42', default='84', choices=[1, 2]),
]
failures = ['2']
failures = ['2', '-z a', '-z 42', '-z 84']
successes = [
('', NS(w=None, x=None, y='spam', z=84)),
('-w', NS(w=None, x=None, y='spam', z=84)),
Expand Down Expand Up @@ -1001,8 +1001,8 @@ class TestPositionalsNargsZeroOrMore(ParserTestCase):
class TestPositionalsNargsZeroOrMoreDefault(ParserTestCase):
"""Test a Positional that specifies unlimited nargs and a default"""

argument_signatures = [Sig('foo', nargs='*', default='bar')]
failures = ['-x']
argument_signatures = [Sig('foo', nargs='*', default='bar', choices=['a', 'b'])]
failures = ['-x', 'bar', 'a c']
successes = [
('', NS(foo='bar')),
('a', NS(foo=['a'])),
Expand Down Expand Up @@ -1035,8 +1035,8 @@ class TestPositionalsNargsOptional(ParserTestCase):
class TestPositionalsNargsOptionalDefault(ParserTestCase):
"""Tests an Optional Positional with a default value"""

argument_signatures = [Sig('foo', nargs='?', default=42)]
failures = ['-x', 'a b']
argument_signatures = [Sig('foo', nargs='?', default=42, choices=['a', 'b'])]
failures = ['-x', 'a b', '42']
successes = [
('', NS(foo=42)),
('a', NS(foo='a')),
Expand All @@ -1049,9 +1049,9 @@ class TestPositionalsNargsOptionalConvertedDefault(ParserTestCase):
"""

argument_signatures = [
Sig('foo', nargs='?', type=int, default='42'),
Sig('foo', nargs='?', type=int, default='42', choices=[1, 2]),
]
failures = ['-x', 'a b', '1 2']
failures = ['-x', 'a b', '1 2', '42']
successes = [
('', NS(foo=42)),
('1', NS(foo=1)),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Fix support of arguments with :ref:`choices` in :mod:`argparse`. Positional
arguments with :ref:`nargs` equal to ``'?'`` or ``'*'`` no longer check
:ref:`default` against ``choices``. Optional arguments with ``nargs`` equal
to ``'?'`` no longer check :ref:`const` against ``choices``.

0 comments on commit 794740c

Please sign in to comment.