bacommon.langstr package¶
Language-agnostic complex strings – the Lstr2 runtime model.
Pure-Python prototype of the language-string-context system (see
docs/initiatives/language-string-context.md in ballistica-internal). The
C++ Lstr2 is a later optimized port of this proven model.
The model lets us pass around minimal, language-independent representations of a complex string (substitutions, plurals, nesting) and resolve to a flat string in a particular language only at display – so one representation serves clients of any language.
- type bacommon.langstr.EncodedLstr = list[str | int | EncodedLstr]¶
- class bacommon.langstr.LangStrDir(apverid: str, tree: WrapperTree, prefix: str = '')[source]¶
Bases:
objectRuntime root/subdir accessor for a generated wrapper package.
- exception bacommon.langstr.LangStrError[source]¶
Bases:
ExceptionA malformed language-string or encode-context operation.
- class bacommon.langstr.LanguageStringDecodeContext(package_index_map: dict[int, str], structures: dict[str, PackageStructure], language: dict[str, dict[str, str | StringSelector]], locale: Locale)[source]¶
Bases:
objectDecodes chunks into flat strings for one target locale.
Holds the
{pkg_int: apverid}map (from the encoder), the package structures, and the per-apverid string values for a single locale.decode()resolves a chunk (recursively rendering nested values) viabacommon.loctext.evaluate().
- class bacommon.langstr.LanguageStringEncodeContext(lstrs: list[Lstr], structures: dict[str, PackageStructure])[source]¶
Bases:
objectEncodes
Lstrvalues into minimal language-free chunks.Built from the batch of values to send: it computes the union of apverids they reference (recursively – nested values know their own apverid) and assigns each a stable integer index.
encode()then emits[pkg_int, str_int, …subs];package_index_mapis the only mapping the consumer needs (string indices resolve from the content-pinned apverid itself).
- class bacommon.langstr.LanguageStringNameDecodeContext(language: dict[str, dict[str, str | StringSelector]], locale: Locale)[source]¶
Bases:
objectDecodes
Lstrvalues directly, by name, for one locale.The name-based counterpart to
LanguageStringDecodeContext: it resolves an in-memoryLstr(carrying itsapverid, stringname, and keywordsubs) straight against per-apverid per-locale values – no integer indices, package-index-map, orPackageStructureneeded, since the subs are self-describing keyword->value pairs. This is the client’s primary path: resolve the referenced packages, gather their per-locale values, then decode eachLstrin the client’s locale.Fail-visible like
LanguageStringDecodeContext– any structural problem yields anLSTR_ERROR:…sentinel (and a logged warning) rather than crashing the caller.
- class bacommon.langstr.Lstr(apverid: str, name: str, subs: dict = <factory>)[source]¶
Bases:
objectA deferred, language-agnostic complex string.
subsmaps each substitution keyword to its value – a flatstr/intor a nestedLstr. A no-arg string has emptysubs. The value carries its own exactapverid(so an encode context can discover the package union from the values themselves) and the string’s logicalname(mapped to its integer index at encode time).This is
@iopreppedso it can be sent directly on the wire (the name-based docui-v2 form). Flatstr/intsubs serialize directly; nested-Lstrsubs are exercised by the in-memory encode / name-decode paths but are not yet directly JSON-serializable here (they graduate with the integer-indexedEncodedLstrform).
- class bacommon.langstr.PackageDef(apverid: str, strings: tuple[StringDef, ...])[source]¶
Bases:
objectLanguage-free definition of one asset-package-version’s strings.
The shared source the encode/decode
PackageStructureand the type-safe wrapper codegen both derive from (in the real system, from an apverid’s resolved listing; in tests, hand-built).
- class bacommon.langstr.PackageStructure(apverid: str, strings: dict[str, tuple[str, ...]])[source]¶
Bases:
objectLanguage-free structure of one asset-package-version.
Maps string names <-> integer indices (assigned in canonical sorted-name order so both ends agree without shipping the mapping) and holds each string’s ordered substitution-keyword list. Carries no translations – encoding needs only this.
- apverid¶
stringsmaps each logical name to its ordered substitution keywords (()for a no-arg string).
- classmethod from_def(pkgdef: PackageDef) PackageStructure[source]¶
Build the encode/decode structure from a package definition.
- class bacommon.langstr.StringDef(path: str, params: tuple[tuple[str, str], ...] = ())[source]¶
Bases:
objectOne string’s language-free definition.
paramsis the ordered list of(keyword, kind)where kind is'text'(a text sub ->str | Lstr) or'count'(the plural pivot ->int);()for a no-arg string. The canonical ordering (sorted keyword) is what fixes the positional substitution order.
- bacommon.langstr.generate_wrapper_module(pkgdef: PackageDef) str[source]¶
Return the
.pysource for a package’s type-safe wrapper.The output is valid but not auto-formatted (the long
_TREEliteral in particular); a caller writing it to the tree should run the formatter before committing.
- bacommon.langstr.package_structure(apverid: str, tree: WrapperTree) PackageStructure[source]¶
Build a
PackageStructurefrom a wrapper’s runtime_TREE.Flattens the nested tree into the
{logical-path: param-keywords}map the encode/decode contexts need – so a consumer of a vendored package just passesmodule.APVERID, module._TREE(both module-level).
- bacommon.langstr.parse_language_blob(text: str) dict[str, str | StringSelector][source]¶
Parse a canonical language blob into a
{name: value}map.The exact inverse of
serialize_language_blob(): reads the top-levelstringsobject, turning each value back into astr(plain) or aStringSelector(a dict). A blob with nostringskey (e.g. a legacy-only package) yields an empty map; malformed values are skipped (fail-soft on the consumer side).
- bacommon.langstr.serialize_language_blob(values: dict[str, str | StringSelector]) str[source]¶
Serialize a per-locale value map to the canonical language blob.
valuesmaps each string’s logical name to its value – a plainstror aStringSelector. Output is deterministic (sorted keys, fixed formatting) for cache stability and diffability.