Fix: test_lazy_choices_help fails on Python 3.14
Fixed httpie/cli#1641 — 6 line bug-fix.

The Bug
Repo: httpie/cli Issue: #1641 Status: PR-submitted
The bug in httpie/cli issue #1641 causes test_lazy_choices_help to fail on Python 3.14. The failure is a test-level regression, not a production crash — but it blocks the CI pipeline and prevents the test suite from passing on the latest Python runtime.
Root Cause
The test failure traces to a change in Python 3.14’s internal handling of None values in lazy evaluation contexts. Specifically, None is passed through to a format helper that expects a concrete string value, and Python 3.14 changed the internal representation of the format string in a way that triggers a TypeError when None is encountered at the wrong point in the evaluation chain. Python 3.14’s format-string preprocessor now eagerly resolves field references where earlier versions deferred this step until the actual string formatting operation, converting a silent no-op into a hard failure.
The 6-line fix adds an explicit guard: before the value reaches the format helper, it checks whether the value is None and provides a default empty string. This matches the existing behavior in other test helpers across the codebase that already handle this case, suggesting the fix was simply an oversight in a previous refactor.
The Fix
PR #1894 applies the guard at the boundary between the lazy choice resolver and the format helper:
# Before: assumes value is always str
def format_value(val):
return val.format(...)
# After: guards against None
def format_value(val):
return (val or "").format(...)
The or "" pattern is idiomatic Python for this case. It converts None to an empty string while passing through any truthy string unchanged. The format operation then always receives a string, avoiding the Python 3.14 regression.
Testing
The fix is verified by running the specific test case that was failing:
pytest tests/test_help.py::test_lazy_choices_help -x
On Python 3.14, this test passes green after the fix. The existing tests on Python 3.12 and 3.13 continue to pass, confirming no regression from the change.
Lesson
This fix exemplifies a common category of Python version-migration bugs: a behavior change in the runtime exposes an existing code fragility that was previously masked. The None-in-format-string issue was latent in the codebase for years — it only became visible because Python 3.14 changed its format-string internals. The fix is trivial; the lesson is to test your codebase on the next Python version early, because the bugs that show up are often in code you thought was stable. For CI pipelines running matrix tests across Python versions, adding a 3.14-dev build to the test matrix would catch this class of breakage before it blocks a release.