Source code for grave_settings.base

# - * -coding: utf - 8 - * -
"""


@author: ☙ Ryan McConnell ❧
"""
from typing import Mapping, Generator, Type

from ordered_set import OrderedSet
from grave_settings.utilities import unwrap_slots_to_base, ext_str_slots
from grave_settings.abstract import IASettings, _KT, _VT, VersionedSerializable
from grave_settings.formatter_settings import FormatterContext


[docs]class Settings(IASettings): __slots__ = 'sd', def __init__(self, *args, initialize_settings=True, **kwargs): self.sd = {} super(Settings, self).__init__(*args, initialize_settings=initialize_settings, **kwargs)
[docs] @classmethod def get_versioning_endpoint(cls) -> Type[VersionedSerializable]: return Settings
[docs] def update(self, __m: Mapping[_KT, _VT], **kwargs: _VT): self.sd.update(__m, **kwargs)
def __contains__(self, item): return item in self.sd def __setitem__(self, key, value): is_new = key not in self if is_new == False: prev = self[key] is_new = value != prev it_t = type(key) if it_t == list or it_t == tuple: set = self for it_ in key[:-1]: set = set[it_] set[key[-1]] = value else: self.sd[key] = value if is_new: self.invalidate() def __getitem__(self, item): it_t = type(item) if it_t == list or it_t == tuple: init_o = self for it_ in item: init_o = init_o[it_] return init_o else: return self.sd[item] def __delitem__(self, itm): del self.sd[itm] def __iter__(self): return iter(self.sd) def __len__(self): return len(self.sd)
[docs] def generate_key_value_pairs(self, **kwargs) -> Generator[tuple[object, object], None, None]: yield from self.sd.items()
[docs] def to_dict(self, context: FormatterContext, **kwargs) -> dict: return self.sd.copy()
#rem_slot_fixed = set()
[docs]class SlotSettings(IASettings): _slot_rems = None __slots__ = tuple() SETTINGS_KEYS = None # @classmethod # def __new__(cls, *args, **kwargs): # if cls not in rem_slot_fixed: # found_slot_rems = False # # # slrm = set() # for tt in generate_hierarchy_to_base(SlotSettings, cls): # if hasattr(tt, '_slot_rems') and tt._slot_rems is not None: # found_slot_rems = True # slrm.update(tt._slot_rems) # # if found_slot_rems: # cls._slot_rems = tuple(slrm) # cls.get_settings_keys = cls.get_settings_keys_rems # else: # cls.get_settings_keys = cls.get_settings_keys_base_slots # rem_slot_fixed.add(cls) # # return super(SlotSettings, cls).__new__(cls) def __init__(self): cls = self.__class__ try: object.__getattribute__(cls, 'SETTINGS_KEYS') except AttributeError: # this whole process is inefficient, but it only happens once so, eh cls.SETTINGS_KEYS = OrderedSet(cls.assemble_settings_keys_from_base(cls)) super().__init__()
[docs] @staticmethod def assemble_settings_keys_from_base(cls: Type) -> tuple: try: ret = object.__getattribute__(cls, 'SETTINGS_KEYS') if ret is not None: # cached return ret except AttributeError: pass keys = OrderedSet() try: keys.update(object.__getattribute__(cls, '__slots__')) except AttributeError: pass for tt in cls.__bases__: if hasattr(tt, 'assemble_settings_keys_from_base'): ins = OrderedSet(tt.assemble_settings_keys_from_base(tt)) ins.update(keys) keys = ins try: _slot_rems = object.__getattribute__(cls, '_slot_rems') if _slot_rems is not None: return tuple(k for k in keys if k not in _slot_rems) except AttributeError: pass return tuple(keys)
[docs] @classmethod def get_versioning_endpoint(cls) -> Type[VersionedSerializable]: return SlotSettings
[docs] def get_settings_keys_rems(self, rems=None) -> set: if rems is None: rems = self._slot_rems return self.get_settings_keys_base_slots().difference(rems)
[docs] def get_settings_keys_base_slots(self) -> set: return unwrap_slots_to_base(SlotSettings, self.__class__)
[docs] def get_settings_keys(self): return self.SETTINGS_KEYS
[docs] def safe_update(self, mapping_obj: Mapping[_KT, _VT], **kwargs: _VT): try: return super(SlotSettings, self).update(mapping_obj, **kwargs) except AttributeError: valid_attrs = self.get_settings_keys() it_t = type(mapping_obj) if it_t == list or it_t == tuple: new_dict = {k: v for k, v in mapping_obj if k in valid_attrs} else: new_dict = {k: v for k, v in mapping_obj.items() if k in valid_attrs} for k, v in kwargs.items(): if k in valid_attrs: new_dict[k] = v return super(SlotSettings, self).update(new_dict)
def __contains__(self, item): return hasattr(self, item) def __setitem__(self, key, value): it_t = type(key) if it_t == list or it_t == tuple: set = self for it_ in key[:-1]: set = set[it_] set[key[-1]] = value else: if it_t is str: setattr(self, key, value) else: raise ValueError('Keys for member settings must be string') self.invalidate() def __getitem__(self, item): it_t = type(item) if it_t == list or it_t == tuple: init_o = self for it_ in item: init_o = init_o[it_] return init_o else: if it_t is str: return getattr(self, item) else: raise ValueError('Keys for member settings must be string') def __delitem__(self, itm): raise ValueError('Cannot delete member of MemberVariableSettings') def __iter__(self): return iter(self.get_settings_keys()) def __len__(self): return len(self.get_settings_keys())
[docs] def generate_key_value_pairs(self) -> Generator[tuple[object, object], None, None]: return ((s, getattr(self, s)) for s in self.get_settings_keys())
[docs] def to_dict(self, context: FormatterContext, **kwargs) -> dict: return dict(self.generate_key_value_pairs())
def __str__(self): return ext_str_slots(self, base=self.get_versioning_endpoint())