GeezerVison is showing github.com — [3.13] gh-61181: Fix support of choices with string value in argparse… · python/cpython@4a9a359
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: Doc/library/argparse.rst +1-1Lines changed: 1 addition & 1 deletion - Display the source diff
- Display the rich diff
| Original file line number | Diff line number | Diff line change |
|---|
@@ -1804,7 +1804,7 @@ Sub-commands | 1804 | 1804 | >>> | 1805 | 1805 | >>> # create the parser for the "b" command | 1806 | 1806 | >>> parser_b = subparsers.add_parser('b', help='b help') | 1807 | | - >>> parser_b.add_argument('--baz', choices='XYZ', help='baz help') | | 1807 | + >>> parser_b.add_argument('--baz', choices=('X', 'Y', 'Z'), help='baz help') | 1808 | 1808 | >>> | 1809 | 1809 | >>> # parse some argument lists | 1810 | 1810 | >>> parser.parse_args(['a', '12']) | |
Collapse file Copy file name to clipboardExpand all lines: Lib/argparse.py +9-5Lines changed: 9 additions & 5 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -2582,11 +2582,15 @@ def _get_value(self, action, arg_string): | 2582 | 2582 |
| 2583 | 2583 | def _check_value(self, action, value): | 2584 | 2584 | # converted value must be one of the choices (if specified) | 2585 | | - if action.choices is not None and value not in action.choices: | 2586 | | - args = {'value': value, | 2587 | | - 'choices': ', '.join(map(repr, action.choices))} | 2588 | | - msg = _('invalid choice: %(value)r (choose from %(choices)s)') | 2589 | | - raise ArgumentError(action, msg % args) | | 2585 | + choices = action.choices | | 2586 | + if choices is not None: | | 2587 | + if isinstance(choices, str): | | 2588 | + choices = iter(choices) | | 2589 | + if value not in choices: | | 2590 | + args = {'value': value, | | 2591 | + 'choices': ', '.join(map(repr, action.choices))} | | 2592 | + msg = _('invalid choice: %(value)r (choose from %(choices)s)') | | 2593 | + raise ArgumentError(action, msg % args) | 2590 | 2594 |
| 2591 | 2595 | # ======================= | 2592 | 2596 | # Help-formatting methods | |
Collapse file Copy file name to clipboardExpand all lines: Lib/test/test_argparse.py +5-5Lines changed: 5 additions & 5 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -686,7 +686,7 @@ class TestOptionalsChoices(ParserTestCase): | 686 | 686 | argument_signatures = [ | 687 | 687 | Sig('-f', choices='abc'), | 688 | 688 | Sig('-g', type=int, choices=range(5))] | 689 | | - failures = ['a', '-f d', '-fad', '-ga', '-g 6'] | | 689 | + failures = ['a', '-f d', '-f ab', '-fad', '-ga', '-g 6'] | 690 | 690 | successes = [ | 691 | 691 | ('', NS(f=None, g=None)), | 692 | 692 | ('-f a', NS(f='a', g=None)), | @@ -2291,14 +2291,14 @@ def _get_parser(self, subparser_help=False, prefix_chars=None, | 2291 | 2291 | parser1_kwargs['aliases'] = ['1alias1', '1alias2'] | 2292 | 2292 | parser1 = subparsers.add_parser('1', **parser1_kwargs) | 2293 | 2293 | parser1.add_argument('-w', type=int, help='w help') | 2294 | | - parser1.add_argument('x', choices='abc', help='x help') | | 2294 | + parser1.add_argument('x', choices=['a', 'b', 'c'], help='x help') | 2295 | 2295 |
| 2296 | 2296 | # add second sub-parser | 2297 | 2297 | parser2_kwargs = dict(description='2 description') | 2298 | 2298 | if subparser_help: | 2299 | 2299 | parser2_kwargs['help'] = '2 help' | 2300 | 2300 | parser2 = subparsers.add_parser('2', **parser2_kwargs) | 2301 | | - parser2.add_argument('-y', choices='123', help='y help') | | 2301 | + parser2.add_argument('-y', choices=['1', '2', '3'], help='y help') | 2302 | 2302 | parser2.add_argument('z', type=complex, nargs='*', help='z help') | 2303 | 2303 |
| 2304 | 2304 | # add third sub-parser | @@ -4628,7 +4628,7 @@ class TestHelpVariableExpansion(HelpTestCase): | 4628 | 4628 | help='x %(prog)s %(default)s %(type)s %%'), | 4629 | 4629 | Sig('-y', action='store_const', default=42, const='XXX', | 4630 | 4630 | help='y %(prog)s %(default)s %(const)s'), | 4631 | | - Sig('--foo', choices='abc', | | 4631 | + Sig('--foo', choices=['a', 'b', 'c'], | 4632 | 4632 | help='foo %(prog)s %(default)s %(choices)s'), | 4633 | 4633 | Sig('--bar', default='baz', choices=[1, 2], metavar='BBB', | 4634 | 4634 | help='bar %(prog)s %(default)s %(dest)s'), | @@ -5291,7 +5291,7 @@ def test_no_argument_actions(self): | 5291 | 5291 | for action in ['store_const', 'store_true', 'store_false', | 5292 | 5292 | 'append_const', 'count']: | 5293 | 5293 | for attrs in [dict(type=int), dict(nargs='+'), | 5294 | | - dict(choices='ab')]: | | 5294 | + dict(choices=['a', 'b'])]: | 5295 | 5295 | self.assertTypeError('-x', action=action, **attrs) | 5296 | 5296 |
| 5297 | 5297 | def test_no_argument_no_const_actions(self): | |
Collapse file Copy file name to clipboard +2Lines changed: 2 additions & 0 deletions - Display the source diff
- Display the rich diff
| Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +Fix support of :ref:`choices` with string value in :mod:`argparse`. Substrings | | 2 | +of the specified string no longer considered valid values. |
|