Source code for rics.translation.offline._translation_map

from typing import Dict, Generic, Iterator, List, Mapping, Optional, Tuple, Type, Union

from rics._internal_support.types import NO_DEFAULT
from rics.translation.offline import DefaultTranslations, MagicDict
from rics.translation.offline._format import Format, FormatType
from rics.translation.offline._format_applier import DefaultFormatApplier, FormatApplier
from rics.translation.offline.types import IdType, NameToSourceDict, NameType, SourcePlaceholderTranslations, SourceType
from rics.utility.misc import tname


[docs]class TranslationMap(Mapping, Generic[NameType, IdType, SourceType]): """Storage class for fetched translations. Args: source_placeholder_translations: Fetched translations ``{source: PlaceholderTranslations}``. name_to_source: Mappings ``{name: source}``, but may be overridden by the user. fmt: A translation format. Must be given to use as a mapping. default: Per-source default values. default_fmt: Alternative format specification to use instead of `fmt` for fallback translation. """ FORMAT_APPLIER_TYPE: Type[FormatApplier] = DefaultFormatApplier """Format applicator implementation type.""" def __init__( self, source_placeholder_translations: SourcePlaceholderTranslations, name_to_source: NameToSourceDict = None, fmt: FormatType = None, default: DefaultTranslations[SourceType] = None, default_fmt: FormatType = None, ) -> None: default_fmt = None if default_fmt is None else Format.parse(default_fmt) self._source_formatters: Dict[SourceType, FormatApplier] = self._make_formatters( source_placeholder_translations, default_fmt=default_fmt, default=default ) self._default_fmt: Optional[Format] = default_fmt self.name_to_source = name_to_source or {} self._fmt = None if fmt is None else Format.parse(fmt) @staticmethod def _make_formatters( source_placeholder_translations: SourcePlaceholderTranslations, default_fmt: Optional[Format], default: Optional[DefaultTranslations[SourceType]], ) -> Dict[SourceType, FormatApplier]: dt: DefaultTranslations = default or DefaultTranslations() return { source: TranslationMap.FORMAT_APPLIER_TYPE( placeholder_translations=placeholder_translations, default=dt.get(source, NO_DEFAULT if default_fmt is None else {}), required_placeholders=None if default_fmt is None else default_fmt.required_placeholders, ) for source, placeholder_translations in source_placeholder_translations.items() }
[docs] def apply(self, name: NameType, fmt: FormatType = None, default_fmt: FormatType = None) -> MagicDict[IdType]: """Create translations for names. Note: ``__getitem__`` delegates to this method. Args: name: A name to translate. fmt: Format to use. If None, fall back to init format. default_fmt: Alternative format for default translation. Resolution: Arg -> init arg, fmt arg, init fmt arg Returns: Translations for `name` as a dict ``{id: translation}``. Raises: ValueError: If ``fmt==None`` and initialized without `fmt`. KeyError: If trying to translate `name` which is not known. """ if fmt is None: # pragma: no cover if self._fmt is None: raise ValueError("No format specified and none given at initialization.") else: fmt = self._fmt fmt = Format.parse(fmt) default_fmt = self._default_fmt if default_fmt is None else Format.parse(default_fmt) source = self.name_to_source[name] return self._source_formatters[source](fmt, default_fmt=default_fmt)
@property def names(self) -> List[NameType]: """Return names that can be translated.""" return list(self.name_to_source) @property def sources(self) -> List[SourceType]: """Return translation source.""" return list(self._source_formatters) @property def name_to_source(self) -> NameToSourceDict: """Return name-to-source mapping.""" return self._name_to_source @name_to_source.setter def name_to_source(self, value: NameToSourceDict) -> None: """Update bindings. Mappings name->source are always added, but may be overridden by the user.""" source_to_source = {source: source for source in self.sources} self._name_to_source: NameToSourceDict = {**source_to_source, **value} def __getitem__(self, item: Union[NameType, Tuple[NameType, FormatType]]) -> MagicDict: name, fmt = item if isinstance(item, tuple) else (item, self._fmt) return self.apply(name, fmt) def __len__(self) -> int: return len(self.names) def __iter__(self) -> Iterator[NameType]: return iter(self.names) def __repr__(self) -> str: sources = ", ".join( {f"'{formatter.source}': {len(formatter)} IDs" for formatter in self._source_formatters.values()} ) return f"{tname(self)}({sources})"