]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.12] gh-61181: Fix support of choices with string value in argparse (GH-124578...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Sun, 29 Sep 2024 08:32:51 +0000 (10:32 +0200)
committerGitHub <noreply@github.com>
Sun, 29 Sep 2024 08:32:51 +0000 (08:32 +0000)
Substrings of the specified string no longer considered valid values.
(cherry picked from commit f1a2417b9e2993e584610851ac004c8b0599b323)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
Doc/library/argparse.rst
Lib/argparse.py
Lib/test/test_argparse.py
Misc/NEWS.d/next/Library/2024-09-26-09-18-09.gh-issue-61181.dwjmch.rst [new file with mode: 0644]

index 8ed44fc809f7b47850c2c959805094415aebe7ff..632185b3f183f5185595fdc3aab64a892efef887 100644 (file)
@@ -1774,7 +1774,7 @@ Sub-commands
      >>>
      >>> # create the parser for the "b" command
      >>> parser_b = subparsers.add_parser('b', help='b help')
-     >>> parser_b.add_argument('--baz', choices='XYZ', help='baz help')
+     >>> parser_b.add_argument('--baz', choices=('X', 'Y', 'Z'), help='baz help')
      >>>
      >>> # parse some argument lists
      >>> parser.parse_args(['a', '12'])
index 8e9289b9d9977d5b7d50ec64ff4abc6ff35f3827..b0ab66ae223a2f53347083e60aa1e5db4c6e93d7 100644 (file)
@@ -2589,11 +2589,15 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
 
     def _check_value(self, action, value):
         # converted value must be one of the choices (if specified)
-        if action.choices is not None and value not in action.choices:
-            args = {'value': value,
-                    'choices': ', '.join(map(repr, action.choices))}
-            msg = _('invalid choice: %(value)r (choose from %(choices)s)')
-            raise ArgumentError(action, msg % args)
+        choices = action.choices
+        if choices is not None:
+            if isinstance(choices, str):
+                choices = iter(choices)
+            if value not in choices:
+                args = {'value': value,
+                        'choices': ', '.join(map(repr, action.choices))}
+                msg = _('invalid choice: %(value)r (choose from %(choices)s)')
+                raise ArgumentError(action, msg % args)
 
     # =======================
     # Help-formatting methods
index c66e803abf4d30fdb0abd9e8178fecd4e13b1bd0..e65c65a0816a2d6e64a07ee9f8d052331f257643 100644 (file)
@@ -686,7 +686,7 @@ class TestOptionalsChoices(ParserTestCase):
     argument_signatures = [
         Sig('-f', choices='abc'),
         Sig('-g', type=int, choices=range(5))]
-    failures = ['a', '-f d', '-fad', '-ga', '-g 6']
+    failures = ['a', '-f d', '-f ab', '-fad', '-ga', '-g 6']
     successes = [
         ('', NS(f=None, g=None)),
         ('-f a', NS(f='a', g=None)),
@@ -2227,14 +2227,14 @@ class TestAddSubparsers(TestCase):
             parser1_kwargs['aliases'] = ['1alias1', '1alias2']
         parser1 = subparsers.add_parser('1', **parser1_kwargs)
         parser1.add_argument('-w', type=int, help='w help')
-        parser1.add_argument('x', choices='abc', help='x help')
+        parser1.add_argument('x', choices=['a', 'b', 'c'], help='x help')
 
         # add second sub-parser
         parser2_kwargs = dict(description='2 description')
         if subparser_help:
             parser2_kwargs['help'] = '2 help'
         parser2 = subparsers.add_parser('2', **parser2_kwargs)
-        parser2.add_argument('-y', choices='123', help='y help')
+        parser2.add_argument('-y', choices=['1', '2', '3'], help='y help')
         parser2.add_argument('z', type=complex, nargs='*', help='z help')
 
         # add third sub-parser
@@ -4397,7 +4397,7 @@ class TestHelpVariableExpansion(HelpTestCase):
             help='x %(prog)s %(default)s %(type)s %%'),
         Sig('-y', action='store_const', default=42, const='XXX',
             help='y %(prog)s %(default)s %(const)s'),
-        Sig('--foo', choices='abc',
+        Sig('--foo', choices=['a', 'b', 'c'],
             help='foo %(prog)s %(default)s %(choices)s'),
         Sig('--bar', default='baz', choices=[1, 2], metavar='BBB',
             help='bar %(prog)s %(default)s %(dest)s'),
@@ -5057,7 +5057,7 @@ class TestInvalidArgumentConstructors(TestCase):
         for action in ['store_const', 'store_true', 'store_false',
                        'append_const', 'count']:
             for attrs in [dict(type=int), dict(nargs='+'),
-                          dict(choices='ab')]:
+                          dict(choices=['a', 'b'])]:
                 self.assertTypeError('-x', action=action, **attrs)
 
     def test_no_argument_no_const_actions(self):
diff --git a/Misc/NEWS.d/next/Library/2024-09-26-09-18-09.gh-issue-61181.dwjmch.rst b/Misc/NEWS.d/next/Library/2024-09-26-09-18-09.gh-issue-61181.dwjmch.rst
new file mode 100644 (file)
index 0000000..801a5fd
--- /dev/null
@@ -0,0 +1,2 @@
+Fix support of :ref:`choices` with string value in :mod:`argparse`. Substrings
+of the specified string no longer considered valid values.