You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
v0.10.0: French, Portuguese and Dutch; locale + test checks in CI
Completes localisations that were half-landed, and closes the gap that let them
land half-finished.
The problem: a language has to exist in three places — the .lproj permission
prompt, CFBundleLocalizations in setup.py, and the UI catalogues in
src/translations.py. fr/pt/nl had the first two but not the third, so macOS
offered the language in the per-app picker and showed a translated permission
prompt while every menu and dialog stayed English. check_locales.py reported
"OK: 7 locales" because it validated .lproj against the plist and had no
knowledge of the UI catalogues.
- src/translations.py: full French, Brazilian-Portuguese and Dutch catalogues
(93 strings each). Portuguese follows pt-BR ("abas", "salvar") to match the
wording already in pt.lproj.
- packaging/check_locales.py: also parses src/translations.py (via AST, never
executing it) and fails when a language is advertised without a UI catalogue,
or has a catalogue without a prompt. Verified it would have caught the state
above: removing fr/pt/nl from CATALOGUES now produces three explicit errors.
- CI: the i18n workflow only triggered on packaging/**, so editing
translations.py — the likeliest source of drift — never ran the check. It also
never ran the test suite. Replaced with checks.yml, which runs locale parity
AND all four suites on src/**, tests/** and packaging/**. Both are
stdlib-only, so no dependency install and it finishes in seconds.
- requirements.txt: certifi refreshed (2026.6.17 -> 2026.7.22) and its floor
raised from >=2024.0.0. It ships the CA roots that verify the self-update
download, so a stale bundle mildly weakens that check.
Checked the 0.9.0 -> 0.10.0 version jump, which is the classic comparison trap
(string compare says "0.10.0" < "0.9.0"): updates._vtuple compares numerically,
so v0.9.0 users are correctly offered v0.10.0 and v0.10.0 doesn't downgrade.
Reviewed and left alone: check_locales.py parses setup.py via AST rather than
executing it, handles UTF-16 BOM, strips comments, and catches duplicate keys
and empty values; two suspected weaknesses (a "//" inside a value, and drift
detection) both probed and found sound. Workflow posture is correct —
contents: read, a concurrency group, no secrets.
Full review written up in the dossier (security-review.md, "Second review").
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>