Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
dj-kaos / settings.py
Size: Mime:
from dataclasses import dataclass

from django.conf import settings


class UNDEFINED_TYPE:
    pass


UNDEFINED = UNDEFINED_TYPE()


@dataclass
class AppSettingsItem:
    name: str


class AppSettingsMeta(type):
    def __new__(mcs, name, bases, dct):
        setting_items = {}
        for k, v in dct.items():
            if isinstance(v, AppSettingsItem):
                setting_items[k] = v

        for k in setting_items.keys():
            dct.pop(k)

        cls = super().__new__(mcs, name, bases, dct)

        for k, v in setting_items.items():
            cached_key = f'_{k}'
            setattr(cls, cached_key, UNDEFINED)
            setattr(cls, k, property(
                (lambda setting_name, cached_key_:
                 lambda self: self._read_setting(setting_name, cached_key_)
                 )(v.name, cached_key),
                (lambda cached_key_:
                 lambda self, value: setattr(self, cached_key_, value)
                 )(cached_key)
            ))

        return cls


class AppSettings(metaclass=AppSettingsMeta):
    defaults: dict
    namespace: str = None

    def __init__(self, user_settings=None):
        self.user_settings = user_settings or getattr(settings, self.namespace, {})

    def _get_setting_from_user_or_defaults(self, name):
        default = self.defaults[name]
        if isinstance(default, dict):
            return {
                **default,
                **self.user_settings.get(name, {})
            }
        try:
            return self.user_settings[name]
        except KeyError:
            return self.defaults[name]

    def _read_setting(self, name, cached_key=None):
        cached_key = cached_key or f'_{name}'
        if getattr(self, cached_key) is UNDEFINED:
            setattr(self, cached_key, self._get_setting_from_user_or_defaults(name))

        return getattr(self, cached_key)


__all__ = (
    'UNDEFINED',
    'AppSettingsItem',
    'AppSettingsMeta',
    'AppSettings',
)