cadrumo.core.i18n.render module

Translation rendering primitives shared across the codebase.

The application and adapter layers import tr() from here so they can render translatable keys without reaching into the CLI entrypoints. python-i18n is initialised lazily on first call.

exception UnmatchedPlaceholderError(*, key, name, rendered)[source]

Bases: CoreError

Raised in strict-placeholder mode when a locale value retains a {name} token.

Indicates that a tr() call site supplies a key whose locale value contains a placeholder not covered by the supplied kwargs (ORPHAN), or that the locale value was never interpolated at all.

Variables:
  • key – The locale translation key that triggered the error.

  • name – The placeholder name that survived substitution.

  • rendered – The partially-rendered string at the time of detection.

Parameters:
Return type:

None

code
exception MissingTranslationError(*, key, locale)[source]

Bases: CoreError

Raised in strict-missing-key mode when a catalogue does not carry a key.

Indicates that a tr() call site names a key absent from the locale, or one whose value is the key itself (the scaffold placeholder for “not translated yet”). Outside strict mode both cases fall back to a humanised label, so a missing string never aborts a filing.

Variables:
  • key – The locale translation key that could not be resolved.

  • locale – The locale whose catalogue was consulted.

Parameters:
Return type:

None

code
register_profile_language_resolver(fn)[source]

Register a callback that resolves the active-profile output language.

The application layer calls this once at startup so core.i18n can read profile-level language preferences without importing application modules directly.

Return type:

None

Parameters:

fn (Callable[[], str | None])

normalise_supported_language(value)[source]

Return the supported-language token value names, or None.

Return type:

str | None

Parameters:

value (object)

output_language()[source]

Resolve the operator-facing output language.

An explicit cadrumo_output_language value on the active Settings (env var, override_settings block, or .env file) wins for one-off sessions and automation. Otherwise the active profile’s output.language key is used. The settings default remains the final fallback and defaults to Spanish for a clean install.

Return type:

str

Returns:

The resolved ISO 639-1 language code.

clear_output_language_cache()[source]

Invalidate cached language resolution after profile/config writes.

Return type:

None

clear_output_language_cache_for_settings_override()[source]

Invalidate at an override_settings boundary the resolver does not own.

override_settings invalidates at both of its boundaries because the cache keys an override block by id(override) and a GC’d block’s address can be reused. That is right for every block an operator or a command opens, and wrong for exactly one: resolving the active profile’s language scopes its own read with override_settings(cadrumo_active_profile=...), so the resolution invalidated the very entry it was about to store.

The version is part of the cache key, so each resolution left the next call keyed to a dead version — a cache that could never serve a hit while a bucket session was bound. Every tr() then paid a full encrypted profile read and three Settings constructions, which is roughly 44 ms each on Windows, where a construction resolves 28 configured paths. One manager repaint resolves a few hundred strings, so re-wording the page after a language change cost around thirteen seconds.

Suppressing the boundary only while a resolution is in flight is what separates the two cases: the profile-write, registration, and CLI-init invalidations all go through clear_output_language_cache() and are never suppressed, so a write that genuinely moves the language is still seen. The flag is a ContextVar, so a resolution running on one task cannot silence another’s boundary, and a thread that never resolved sees the default and invalidates normally.

Return type:

None

tr(translation_key, /, **kwargs)[source]

Render an abstract translation key in the configured output language.

Parameters:
  • translation_key (str) – The abstract namespace key to render (e.g., "cli.auth.purpose"). Positional-only so callers can pass interpolation kwargs named key without collision.

  • **kwargs (object) – Interpolation arguments for python-i18n.

Return type:

str

Returns:

The translated string.

Raises:
  • UnmatchedPlaceholderError – When strict-placeholder mode is active and the rendered string still contains an un-interpolated {name} token.

  • MissingTranslationError – When strict-missing-key mode is active, the catalogue does not carry translation_key, and no explicit default was supplied.

extract_placeholders(value)[source]

Return interpolation names consumed by the production renderer.

The renderer first replaces %{name} tokens and then delegates {name} tokens to str.format(). Parsing the second form through string.Formatter preserves conversions and specifications. Root kwargs consumed by attribute and index fields are returned, and nested replacement fields inside format specifications are inspected recursively. Escaped braces and brace-delimited prose are excluded. For malformed strings, independently valid fields are recovered without representing the malformed format string itself as complete or renderable.

Parameters:

value (str) – Locale scalar to inspect.

Return type:

frozenset[str]

Returns:

The unique placeholder names used by either interpolation pass.

override_locales_root(root)[source]

Resolve catalogues from root instead of the packaged resources.

The renderer’s miss semantics — an absent key and a key-echo value are both misses (_lookup_translation()) — can only be exercised against a catalogue that carries the defect, and the shipped catalogues are gated echo-free. This override is the sanctioned seam for pointing resolution at a fixture catalogue, mirroring override_settings(); the packaged resources stay the sole source otherwise.

Return type:

Generator[None]

Parameters:

root (Path)

locale_map(locale)[source]
Return type:

Mapping[str, str | None]

Parameters:

locale (str)

lookup_translation(translation_key, /, *, locale)[source]

Return one authored locale scalar without humanising a missing value.

None and the catalogue scaffold convention value == key both mean that the selected locale has no authored value. Domain resolvers use this primitive when they own a stricter fallback policy than the operator-facing tr() convenience surface.

Return type:

str | None

Parameters:
  • translation_key (str)

  • locale (str)

lookup_translation_entry(translation_key, /, *, locale)[source]

Return catalogue membership separately from its optional scalar value.

Return type:

tuple[bool, str | None]

Parameters:
  • translation_key (str)

  • locale (str)