https://github.com/python/cpython/commit/53a7f76501923059188922be231db855265fe9a4
commit: 53a7f76501923059188922be231db855265fe9a4
branch: main
author: Savannah Ostrowski <[email protected]>
committer: savannahostrowski <[email protected]>
date: 2026-05-04T21:51:48Z
summary:
GH-130750: Restore quoting of choices in argparse error messages to match
documentation and improve clarity (#144983)
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
M Lib/test/test_timeit.py
diff --git a/Lib/argparse.py b/Lib/argparse.py
index d91707d9eec546..9ea6b32163a9d1 100644
--- a/Lib/argparse.py
+++ b/Lib/argparse.py
@@ -2758,7 +2758,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 e0c32976fd6f0d..4799c9947dd3ee 100644
--- a/Lib/test/test_argparse.py
+++ b/Lib/test/test_argparse.py
@@ -1123,7 +1123,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'],
)
@@ -2392,7 +2392,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
)
@@ -2402,7 +2402,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,
)
@@ -2415,7 +2415,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,
)
@@ -2427,7 +2427,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,
)
@@ -2438,7 +2438,7 @@ def test_wrong_argument_with_suggestion_explicit(self):
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 @@ 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,
)
@@ -2468,7 +2468,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/Lib/test/test_timeit.py b/Lib/test/test_timeit.py
index 81f1a9c97393d1..a2a09f9de61490 100644
--- a/Lib/test/test_timeit.py
+++ b/Lib/test/test_timeit.py
@@ -359,7 +359,7 @@ def test_main_with_time_unit(self):
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
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]