https://github.com/python/cpython/commit/a458589a7e224cc45a868af2eb727e4f898e8d22
commit: a458589a7e224cc45a868af2eb727e4f898e8d22
branch: 3.14
author: Savannah Ostrowski <[email protected]>
committer: savannahostrowski <[email protected]>
date: 2026-05-04T22:22:54Z
summary:

[3.14] GH-130750: Restore quoting of choices in argparse error messag… (#149385)

[3.14] GH-130750: Restore quoting of choices in argparse error messages to 
match documentation and improve clarity (GH-144983)
(cherry picked from commit 53a7f76501923059188922be231db855265fe9a4)

files:
A Misc/NEWS.d/next/Library/2026-02-19-04-40-57.gh-issue-130750.0hW52O.rst
M Lib/argparse.py
M Lib/test/test_argparse.py

diff --git a/Lib/argparse.py b/Lib/argparse.py
index 8cf856943002de..24f4740562d015 100644
--- a/Lib/argparse.py
+++ b/Lib/argparse.py
@@ -2678,7 +2678,7 @@ def _check_value(self, action, value):
 
         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):
diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py
index 8331d021813424..627e395c49b194 100644
--- a/Lib/test/test_argparse.py
+++ b/Lib/test/test_argparse.py
@@ -1045,7 +1045,7 @@ def test_invalid_enum_value_raises_error(self):
         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'],
         )
@@ -2313,7 +2313,7 @@ def test_wrong_argument_error_with_suggestions(self):
         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
         )
 
@@ -2323,7 +2323,7 @@ def test_wrong_argument_error_no_suggestions(self):
         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,
         )
 
@@ -2336,7 +2336,7 @@ def test_wrong_argument_subparsers_with_suggestions(self):
             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,
         )
 
@@ -2348,7 +2348,7 @@ def test_wrong_argument_subparsers_no_suggestions(self):
         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,
         )
 
@@ -2358,7 +2358,7 @@ def test_wrong_argument_no_suggestion_implicit(self):
         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,
         )
 
@@ -2378,7 +2378,7 @@ def test_suggestions_choices_int(self):
         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,
         )
 
@@ -2388,7 +2388,7 @@ def test_suggestions_choices_mixed_types(self):
         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,
         )
 
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
index 00000000000000..8bca48ab159476
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-02-19-04-40-57.gh-issue-130750.0hW52O.rst
@@ -0,0 +1,2 @@
+Restore quoting of choices in :mod:`argparse` error messages for improved 
clarity and consistency with documentation.
+

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to