betty.locale.localizable.config - Betty documentation

Hide navigation sidebar
Hide table of contents sidebar
Skip to content
Back to top
Toggle table of contents sidebar

# Source code for betty.locale.localizable.config

    """
    Provide localizable configuration.
    """

    from contextlib import suppress
    from typing import Self, final, overload, cast, TypeVar

    from typing_extensions import override

    from betty.assertion import assert_len
    from betty.config import Configuration
    from betty.locale import UNDETERMINED_LOCALE
    from betty.locale.localizable import (
        ShorthandStaticTranslations,
        StaticTranslationsLocalizable,
    )
    from betty.locale.localizable.assertion import assert_static_translations
    from betty.serde.dump import Dump

    _T = TypeVar("_T")

    @final
    class StaticTranslationsLocalizableConfiguration(
        Configuration, StaticTranslationsLocalizable
    ):
        """
        Provide configuration for a :py:class:`betty.locale.localizable.Localizable`.

        Read more at :doc:`multiple translations </usage/configuration/static-translations-localizable>`.
        """

        @override
        def load(self, dump: Dump) -> None:
            self._translations.clear()

            translations = assert_static_translations()(dump)
            assert_len(minimum=1 if self._required else 0)(translations)
            for locale, translation in translations.items():
                self[locale] = translation

        @override
        def dump(self) -> Dump:
            translation_count = len(self._translations)
            if translation_count == 0:
                return {}
            elif translation_count == 1:
                with suppress(KeyError):
                    return self._translations[UNDETERMINED_LOCALE]
            return dict(self._translations)

    class _StaticTranslationsLocalizableConfigurationAttr:
        _required: bool

        def __init__(self, attr_name: str):
            self._attr_name = f"_{attr_name}"

        @overload
        def __get__(self, instance: None, owner: type[object]) -> Self:
            pass

        @overload
        def __get__(
            self, instance: _T, owner: type[_T]
        ) -> StaticTranslationsLocalizableConfiguration:
            pass

        def __get__(
            self, instance: object | None, owner: type[object]
        ) -> StaticTranslationsLocalizableConfiguration | Self:
            if instance is None:
                return self  # type: ignore[return-value]
            try:
                return cast(
                    StaticTranslationsLocalizableConfiguration,
                    getattr(instance, self._attr_name),
                )
            except AttributeError:
                value = StaticTranslationsLocalizableConfiguration(required=self._required)
                setattr(instance, self._attr_name, value)
                return value

        def __set__(self, instance: object, value: ShorthandStaticTranslations) -> None:
            self.__get__(instance, type(instance)).replace(value)

    @final
    class RequiredStaticTranslationsLocalizableConfigurationAttr(
        _StaticTranslationsLocalizableConfigurationAttr
    ):
        """
        An instance attribute that contains :py:class:`betty.locale.localizable.config.StaticTranslationsLocalizableConfiguration`.
        """

        _required = True

    @final
    class OptionalStaticTranslationsLocalizableConfigurationAttr(
        _StaticTranslationsLocalizableConfigurationAttr
    ):
        """
        An instance attribute that contains :py:class:`betty.locale.localizable.config.StaticTranslationsLocalizableConfiguration`.
        """

        _required = False

        def __delete__(self, instance: object) -> None:
            self.__get__(instance, type(instance)).replace({})