refactor(i18n): make the shipped catalog the single source of truth
PR #68 restated its own translation data in Python: a 60-line TRANSLATED_SELECT_STATES table of frozensets duplicating every entity.select.*.state key, a second _TRANSLATED_COURSE_TABLES table naming which course tables have translations, and a strings.json that was a 835-line byte-for-byte copy of translations/en.json save 43 [%key:...%] references. Each needed hand-syncing, and one was already drifting. Home Assistant loads exactly one file per language for a custom integration -- translations/<lang>.json. It never reads strings.json and never resolves [%key:...%]; both belong to Core's build tooling, which custom integrations don't run through (hassfest skips a missing strings.json and validates translations/en.json instead). So en.json is the source, and the new catalog.py reads the keys and states back out of it for the two decisions Python genuinely has to make: - select._display() normalizes a raw Samsung option to a lowercase state key only when the catalog knows it, else leaves the vendor's casing alone. Derived sets are identical to the removed literals. - laundry.cycle_select() keys off a device-reported course table only when that table has an entry, else falls back to the name-only 'cycle' key. Translating Table_00 is now a translations-only change. Also fixes six names that had already drifted between the Python descriptors and the catalog, restoring HA's sentence case for two generic ones (Auto release dry, Bubble soak) and taking the catalog's wording for the rest, and adds a test so the vestigial descriptor names can't silently disagree with the UI again. Claude-Session: https://claude.ai/code/session_01GiibJZZLWVvyxq7mc7EDNp
This commit is contained in:
@@ -109,10 +109,15 @@ Any select whose options are raw device codes (course/cycle, and code-valued
|
||||
settings) must render through translations, not Python:
|
||||
- Set `translation_key='<family>_cycle'` (or similar) on the `SelectDesc`;
|
||||
`options`/`options_field` supply the **raw** codes.
|
||||
- Add the labels to **both** `strings.json` and `translations/en.json` under
|
||||
- Add the labels to `translations/en.json` under
|
||||
`entity.select.<translation_key>.state.<code>`, with the code **lowercased**
|
||||
(e.g. `"16": "Cotton"`). Codes with no entry render as the raw code — that's
|
||||
the cue to identify and name them.
|
||||
- `en.json` is the only place these live: there is no `strings.json` (Home
|
||||
Assistant doesn't read one from a custom integration), and `select.py`
|
||||
derives its normalization set from the catalog, so there is no Python list
|
||||
to keep in sync. Every other language must mirror `en.json` key for key —
|
||||
`tests/test_translations.py` enforces that.
|
||||
|
||||
## 6. Coverage discipline: bound or ignored
|
||||
|
||||
|
||||
Reference in New Issue
Block a user