95 lines
2.4 KiB
Python
95 lines
2.4 KiB
Python
import copy
|
|
import pprint
|
|
import tomllib
|
|
import hashlib
|
|
from typing import Any
|
|
from pathlib import Path
|
|
|
|
from symconf.util import deep_update
|
|
|
|
|
|
class DictReader:
|
|
def __init__(self, toml_path=None):
|
|
self._config = {}
|
|
self.toml_path = toml_path
|
|
|
|
if toml_path is not None:
|
|
self._config = self._load_toml(toml_path)
|
|
|
|
def __str__(self):
|
|
return pprint.pformat(self._config, indent=4)
|
|
|
|
@staticmethod
|
|
def _load_toml(toml_path) -> dict[str, Any]:
|
|
return tomllib.loads(Path(toml_path).read_text())
|
|
|
|
@classmethod
|
|
def from_dict(cls, config_dict):
|
|
new_instance = cls()
|
|
new_instance._config = copy.deepcopy(config_dict)
|
|
return new_instance
|
|
|
|
def update(self, config, in_place=False):
|
|
new_config = deep_update(self._config, config._config)
|
|
|
|
if in_place:
|
|
self._config = new_config
|
|
return self
|
|
|
|
return self.from_dict(new_config)
|
|
|
|
def copy(self):
|
|
return self.from_dict(copy.deepcopy(self._config))
|
|
|
|
def get_subconfig(self, key): pass
|
|
|
|
def get(self, key, default=None):
|
|
keys = key.split('.')
|
|
|
|
subconfig = self._config
|
|
for subkey in keys[:-1]:
|
|
subconfig = subconfig.get(subkey)
|
|
|
|
if type(subconfig) is not dict:
|
|
return default
|
|
|
|
return subconfig.get(keys[-1], default)
|
|
|
|
def set(self, key, value):
|
|
keys = key.split('.')
|
|
|
|
subconfig = self._config
|
|
for subkey in keys[:-1]:
|
|
if subkey in subconfig:
|
|
subconfig = subconfig[subkey]
|
|
|
|
if type(subconfig) is not dict:
|
|
logger.debug(
|
|
'Attempting to set nested key with an existing non-dict parent'
|
|
)
|
|
return False
|
|
|
|
continue
|
|
|
|
subdict = {}
|
|
subconfig[subkey] = subdict
|
|
subconfig = subdict
|
|
|
|
subconfig.update({ keys[-1]: value })
|
|
return True
|
|
|
|
def generate_hash(self, exclude_keys=None):
|
|
inst_copy = self.copy()
|
|
|
|
if exclude_keys is not None:
|
|
for key in exclude_keys:
|
|
inst_copy.set(key, None)
|
|
|
|
items = inst_copy._config.items()
|
|
|
|
# create hash from config options
|
|
config_str = str(sorted(items))
|
|
return hashlib.md5(config_str.encode()).hexdigest()
|
|
|
|
|