simvx.core.i18n

Internationalization (i18n) — translation and localization system.

Provides translation lookup with locale fallback, plural rules, and format string interpolation. Supports CSV and JSON translation files.

Public API: from simvx.core import TranslationServer, tr

ts = TranslationServer.instance()
ts.load_json("translations.json")
ts.set_locale("fr")

label.text = tr("greeting", name=player_name)  # "Bonjour, {name}!"

Module Contents

Classes

PluralRules

Basic CLDR-style plural category selection for common locales.

TranslationServer

Singleton translation server managing locale state and translation lookup.

Functions

tr

Translate key using the global TranslationServer.

locale_from_system

Detect the system locale and return a normalised locale code.

Data

API

simvx.core.i18n.log

‘getLogger(…)’

simvx.core.i18n.__all__

[‘TranslationServer’, ‘tr’, ‘PluralRules’, ‘locale_from_system’]

class simvx.core.i18n.PluralRules

Basic CLDR-style plural category selection for common locales.

Returns a plural category string: “zero”, “one”, “two”, “few”, “many”, “other”. Rules are simplified from the full CLDR specification but cover the most common cases.

static get_plural_form(n: int | float, locale_code: str = 'en') str

Return the plural category for n in the given locale.

Args: n: The count value (typically a non-negative number). locale_code: Base locale code (e.g. “en”, “fr”, “ar”). Region suffixes are stripped.

Returns: One of “zero”, “one”, “two”, “few”, “many”, “other”.

class simvx.core.i18n.TranslationServer

Singleton translation server managing locale state and translation lookup.

Stores translations as {locale: {key: value}} and supports:

  • Locale fallback chain (e.g. “fr_CA” -> “fr” -> default locale)

  • Python format string interpolation via **kwargs

  • CSV and JSON file loading

  • Plural form lookup

Example: ts = TranslationServer.instance() ts.add_translation(“en”, “greeting”, “Hello, {name}!”) ts.add_translation(“fr”, “greeting”, “Bonjour, {name}!”) ts.set_locale(“fr”) print(ts.translate(“greeting”, name=”World”)) # “Bonjour, World!”

Initialization

classmethod instance() simvx.core.i18n.TranslationServer

Return the global singleton, creating it on first access.

set_locale(locale_code: str) None

Set the active locale (e.g. “en”, “fr”, “ja”, “fr_CA”).

Args: locale_code: An IETF-style language tag. Case-insensitive storage; internally normalised to lowercase with underscores.

get_locale() str

Return the current active locale string.

set_default_locale(locale_code: str) None

Set the fallback locale used when a key is missing in the active locale.

get_default_locale() str

Return the default/fallback locale string.

get_available_locales() list[str]

Return a sorted list of locales that have at least one translation.

add_translation(locale_code: str, key: str, value: str) None

Add a single translation entry.

Args: locale_code: Target locale (e.g. “en”, “fr”). key: Translation key. value: Translated string, may contain {placeholder} fields.

add_translations(locale_code: str, entries: dict[str, str]) None

Bulk-add translations for a locale.

Args: locale_code: Target locale. entries: Mapping of key -> translated string.

load_csv(path: str | pathlib.Path) None

Load translations from a CSV file.

Expected CSV format (first column is the key, remaining columns are locales): key,en,fr,ja greeting,Hello,Bonjour,こんにちは farewell,Goodbye,Au revoir,さようなら

The first row is the header defining locale codes.

Args: path: Path to the CSV file.

load_json(path: str | pathlib.Path) None

Load translations from a JSON file.

Expected JSON format (outer keys are locale codes): { “en”: {“greeting”: “Hello”, “farewell”: “Goodbye”}, “fr”: {“greeting”: “Bonjour”, “farewell”: “Au revoir”} }

Args: path: Path to the JSON file.

load_dict(data: dict[str, dict[str, str]]) None

Load translations from an in-memory dict (same format as JSON).

Args: data: {locale: {key: value, ...}, ...}

clear() None

Remove all loaded translations and reset locale to default.

translate(key: str, **kwargs: object) str

Look up a translation key in the current locale with fallback.

If the key is not found in any locale in the fallback chain, the key itself is returned (useful for debugging missing translations).

Args: key: Translation key. **kwargs: Values for str.format() interpolation in the translated string.

Returns: The translated (and optionally interpolated) string, or the raw key if not found.

translate_plural(key: str, count: int | float, **kwargs: object) str

Look up a plural-aware translation key.

Determines the plural category for count in the current locale, then looks up key_<category> (e.g. “item_one”, “item_other”). Falls back to key_other, then to the bare key.

The count value is automatically available as {count} in the translated string.

Args: key: Base translation key (e.g. “item”). count: The quantity determining the plural form. **kwargs: Additional format values.

Returns: The translated and interpolated plural string.

simvx.core.i18n.tr(key: str, **kwargs: object) str

Translate key using the global TranslationServer.

Shorthand for TranslationServer.instance().translate(key, **kwargs).

Args: key: Translation key. **kwargs: Format string interpolation values.

Returns: Translated string, or the key itself if not found.

simvx.core.i18n.locale_from_system() str

Detect the system locale and return a normalised locale code.

Uses locale.getdefaultlocale() (deprecated but widely available) with a fallback to locale.getlocale(), then LANG environment variable.

Returns: Locale string such as “en”, “fr_ca”, “ja”, or “en” as ultimate fallback.