]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
GH-130750: Restore quoting of choices in argparse error messages to match documentati...
authorSavannah Ostrowski <savannah@python.org>
Mon, 4 May 2026 21:51:48 +0000 (14:51 -0700)
committerGitHub <noreply@github.com>
Mon, 4 May 2026 21:51:48 +0000 (21:51 +0000)
Lib/argparse.py
Lib/test/test_argparse.py
Lib/test/test_timeit.py
Misc/NEWS.d/next/Library/2026-02-19-04-40-57.gh-issue-130750.0hW52O.rst [new file with mode: 0644]

index d91707d9eec54645c8fdb0346b13363326803ba4..9ea6b32163a9d192a9aa2e2b971b7fe3a5dd6f2c 100644 (file)
@@ -2758,7 +2758,7 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
 
         if value not in choices:
             args = {'value': str(value),
-                    'choices': ', '.join(map(str, action.choices))}
+                    'choices': ', '.join(repr(str(choice)) for choice in action.choices)}
             msg = _('invalid choice: %(value)r (choose from %(choices)s)')
 
             if self.suggest_on_error and isinstance(value, str):
index e0c32976fd6f0d1b0433ae76c49bdefb37c6bc90..4799c9947dd3eeef02871b6b2a2c86d130acce63 100644 (file)
@@ -1123,7 +1123,7 @@ class TestStrEnumChoices(TestCase):
         parser.add_argument('--color', choices=self.Color)
         self.assertRaisesRegex(
             argparse.ArgumentError,
-            r"invalid choice: 'yellow' \(choose from red, green, blue\)",
+            r"invalid choice: 'yellow' \(choose from 'red', 'green', 'blue'\)",
             parser.parse_args,
             ['--color', 'yellow'],
         )
@@ -2392,7 +2392,7 @@ class TestArgumentAndSubparserSuggestions(TestCase):
         with self.assertRaises(ArgumentParserError) as excinfo:
             parser.parse_args(('bazz',))
         self.assertIn(
-            "error: argument foo: invalid choice: 'bazz', maybe you meant 'baz'? (choose from bar, baz)",
+            "error: argument foo: invalid choice: 'bazz', maybe you meant 'baz'? (choose from 'bar', 'baz')",
             excinfo.exception.stderr
         )
 
@@ -2402,7 +2402,7 @@ class TestArgumentAndSubparserSuggestions(TestCase):
         with self.assertRaises(ArgumentParserError) as excinfo:
             parser.parse_args(('bazz',))
         self.assertIn(
-            "error: argument foo: invalid choice: 'bazz' (choose from bar, baz)",
+            "error: argument foo: invalid choice: 'bazz' (choose from 'bar', 'baz')",
             excinfo.exception.stderr,
         )
 
@@ -2415,7 +2415,7 @@ class TestArgumentAndSubparserSuggestions(TestCase):
             parser.parse_args(('baz',))
         self.assertIn(
             "error: argument {foo,bar}: invalid choice: 'baz', maybe you meant"
-             " 'bar'? (choose from foo, bar)",
+             " 'bar'? (choose from 'foo', 'bar')",
             excinfo.exception.stderr,
         )
 
@@ -2427,7 +2427,7 @@ class TestArgumentAndSubparserSuggestions(TestCase):
         with self.assertRaises(ArgumentParserError) as excinfo:
             parser.parse_args(('baz',))
         self.assertIn(
-            "error: argument {foo,bar}: invalid choice: 'baz' (choose from foo, bar)",
+            "error: argument {foo,bar}: invalid choice: 'baz' (choose from 'foo', 'bar')",
             excinfo.exception.stderr,
         )
 
@@ -2438,7 +2438,7 @@ class TestArgumentAndSubparserSuggestions(TestCase):
             parser.parse_args(('bazz',))
         self.assertIn(
             "error: argument foo: invalid choice: 'bazz', maybe you meant"
-             " 'baz'? (choose from bar, baz)",
+             " 'baz'? (choose from 'bar', 'baz')",
             excinfo.exception.stderr,
         )
 
@@ -2458,7 +2458,7 @@ class TestArgumentAndSubparserSuggestions(TestCase):
         with self.assertRaises(ArgumentParserError) as excinfo:
             parser.parse_args(('3',))
         self.assertIn(
-            "error: argument foo: invalid choice: '3' (choose from 1, 2)",
+            "error: argument foo: invalid choice: '3' (choose from '1', '2')",
             excinfo.exception.stderr,
         )
 
@@ -2468,7 +2468,7 @@ class TestArgumentAndSubparserSuggestions(TestCase):
         with self.assertRaises(ArgumentParserError) as excinfo:
             parser.parse_args(('3',))
         self.assertIn(
-            "error: argument foo: invalid choice: '3' (choose from 1, 2)",
+            "error: argument foo: invalid choice: '3' (choose from '1', '2')",
             excinfo.exception.stderr,
         )
 
index 81f1a9c97393d129b74ee8bb66af50991f4ef64e..a2a09f9de61490a9071255a84049487455169c14 100644 (file)
@@ -359,7 +359,7 @@ class TestTimeit(unittest.TestCase):
                 seconds_per_increment=0.003, switches=["-u", "parsec"]
             )
         self.assertIn(
-            "choose from nsec, usec, msec, sec", error_stringio.getvalue()
+            "choose from 'nsec', 'usec', 'msec', 'sec'", error_stringio.getvalue()
         )
 
     def test_main_exception(self):
diff --git a/Misc/NEWS.d/next/Library/2026-02-19-04-40-57.gh-issue-130750.0hW52O.rst b/Misc/NEWS.d/next/Library/2026-02-19-04-40-57.gh-issue-130750.0hW52O.rst
new file mode 100644 (file)
index 0000000..8bca48a
--- /dev/null
@@ -0,0 +1,2 @@
+Restore quoting of choices in :mod:`argparse` error messages for improved clarity and consistency with documentation.
+