Description
The tests/test_cli.py::test_invalid_command[py_3.14-invalidCommand] test started failing on Python 3.14.5 (released May 10, 2026) because CPython restored quoting of choices in argparse error messages:
gh-130750: Restore quoting of choices in argparse error messages for improved clarity and consistency with documentation.
-- 3.14.5 changelog
| Python |
argparse "invalid choice" format |
| 3.10, 3.11 |
(choose from 'init', 'commit', ...) (quoted) |
| 3.12 |
mixed |
| 3.13, 3.14.0–3.14.4 |
(choose from init, commit, ...) (unquoted) |
| 3.14.5+ |
(choose from 'init', 'commit', ...) (quoted, restored) |
The checked-in fixture tests/test_cli/test_invalid_command_py_3_14_invalidCommand_.txt was generated against 3.14.4 (unquoted), so it no longer matches.
Reproduction
uv run pytest tests/test_cli.py::test_invalid_command
Master's last successful CI run was on 2026-05-09 (commit 1eb8cde6) when the GitHub-hosted runner still had Python 3.14.4; runs on or after 2026-05-11 fail with the diff below.
Observed failure
FAILED tests/test_cli.py::test_invalid_command[py_3.14-invalidCommand] - AssertionError: FILES DIFFER
-cz: error: argument {...}: invalid choice: 'invalidCommand' (choose from init, commit, ...)
+cz: error: argument {...}: invalid choice: 'invalidCommand' (choose from 'init', 'commit', ...)
Full log: https://github.com/commitizen-tools/commitizen/actions/runs/25649120897/job/75283769681
Scope
Only the 1 test_invalid_command_py_3_14_invalidCommand_.txt fixture is affected by gh-130750 (the companion --invalid-arg case uses the metavar, not the choice list). The other 60+ Python-version-keyed fixtures (test_command_shows_description_when_use_help_option_py_3_*_*.txt, test_no_argv_py_3_*_.txt) capture argparse help text, which is unaffected by this change.
Suggested fix (short-term)
Skip the affected test_invalid_command parametrization on Python ≥ 3.14.5 until upstream stabilizes:
@pytest.mark.parametrize(
"arg",
[
"--invalid-arg",
pytest.param(
"invalidCommand",
marks=pytest.mark.skipif(
(3, 14, 5) <= sys.version_info < (3, 15),
reason=(
"argparse error format changed in Python 3.14.5 (gh-130750); "
"fixture matches 3.14.0-4 unquoted format"
),
),
),
],
)
Surfaced while working on #1846; this skip unblocks CI without changing PR scope. Implemented in #1991.
Future enhancement (still open after #1991)
Argparse error output has churned across Python patch releases (3.10/3.11 quoted → 3.13/3.14.0–4 unquoted → 3.14.5 quoted). A more durable approach worth considering once the codebase is more stable:
Normalize argparse error output before file_regression.check() — e.g., strip surrounding quotes around choose from items, or replace the variable parts with placeholders:
def _normalize_argparse_error(text: str) -> str:
# Collapse "'init', 'commit'" and "init, commit" to a single canonical form
text = re.sub(
r"\(choose from [^)]+\)",
"(choose from <CHOICES>)",
text,
)
return text
# Usage:
file_regression.check(_normalize_argparse_error(err), extension=".txt")
That would let us delete the per-Python-version fixtures for test_invalid_command[invalidCommand] and stop chasing argparse formatting changes. #1991 only implements the short-term skip; this enhancement is still open.
Description
The
tests/test_cli.py::test_invalid_command[py_3.14-invalidCommand]test started failing on Python 3.14.5 (released May 10, 2026) because CPython restored quoting of choices in argparse error messages:(choose from 'init', 'commit', ...)(quoted)(choose from init, commit, ...)(unquoted)(choose from 'init', 'commit', ...)(quoted, restored)The checked-in fixture
tests/test_cli/test_invalid_command_py_3_14_invalidCommand_.txtwas generated against 3.14.4 (unquoted), so it no longer matches.Reproduction
Master's last successful CI run was on 2026-05-09 (commit
1eb8cde6) when the GitHub-hosted runner still had Python 3.14.4; runs on or after 2026-05-11 fail with the diff below.Observed failure
Full log: https://github.com/commitizen-tools/commitizen/actions/runs/25649120897/job/75283769681
Scope
Only the 1
test_invalid_command_py_3_14_invalidCommand_.txtfixture is affected by gh-130750 (the companion--invalid-argcase uses the metavar, not the choice list). The other 60+ Python-version-keyed fixtures (test_command_shows_description_when_use_help_option_py_3_*_*.txt,test_no_argv_py_3_*_.txt) capture argparse help text, which is unaffected by this change.Suggested fix (short-term)
Skip the affected
test_invalid_commandparametrization on Python ≥ 3.14.5 until upstream stabilizes:Surfaced while working on #1846; this skip unblocks CI without changing PR scope. Implemented in #1991.
Future enhancement (still open after #1991)
Argparse error output has churned across Python patch releases (3.10/3.11 quoted → 3.13/3.14.0–4 unquoted → 3.14.5 quoted). A more durable approach worth considering once the codebase is more stable:
Normalize argparse error output before
file_regression.check()— e.g., strip surrounding quotes aroundchoose fromitems, or replace the variable parts with placeholders:That would let us delete the per-Python-version fixtures for
test_invalid_command[invalidCommand]and stop chasing argparse formatting changes. #1991 only implements the short-term skip; this enhancement is still open.