[docs]classSettings:r"""This class represents the settings that you user has chosen. If a setting is not found, ``None`` is returned instead. .. container:: operations .. describe:: x['setting name'] Get a setting by key similiar to a dictionary .. describe:: x['setting name', 'default'] Get a setting by key similiar to a dictionary, with a custom default. .. describe:: x['setting name'] = "new value" Change a settings value like a dictionary .. describe:: x.setting_name Get a setting by name like an attribute .. describe:: x.setting_name = "new value" Change a settings value like an attribute """_data:RawSettings_changes:RawSettingsdef__init__(self,data:RawSettings,*,no_update:bool=False)->None:self._data=dataself._changes={}self._no_update=no_update@overloaddef__getitem__(self,key:str,/)->Any:...@overloaddef__getitem__(self,key:tuple[str,Any],/)->Any:...def__getitem__(self,key:tuple[str,Any]|str)->Any:ifisinstance(key,str):default=Noneelse:key,default=keyreturnself._data.get(key,default)def__setitem__(self,key:str,value:Any)->None:self._data[key]=valueself._changes[key]=valuedef__getattribute__(self,name:str)->Any:ifname.startswith("_"):try:returnsuper().__getattribute__(name)exceptAttributeErrorase:raiseAttributeError(f"{e}. Settings that start with an underscore (_) can only be accessed by the __getitem__ method. Ex: settings['_key']")fromNonereturnself.__getitem__(name)def__setattr__(self,name:str,value:Any)->None:ifname.startswith("_"):returnsuper().__setattr__(name,value)self.__setitem__(name,value)def_update(self,data:RawSettings)->None:ifself._no_update:LOG.debug(f"Received a settings update, ignoring. {data=}")else:LOG.debug(f"Updating settings. Before: {self._data}, after: {data}")self._data=datadef_get_updates(self)->RawSettings:try:returnself._changesfinally:LOG.debug(f"Resetting setting changes: {self._changes}")self._changes={}def__repr__(self)->str:returnf"<Settings current={self._data!r}, pending_changes={self._changes}>"