MIGAVis / utils /config.py
McHz1s's picture
Initial commit
d6ee7b8
import yaml
from collections import OrderedDict, abc as container_abc
from utils.my_containers import ObjDict
from utils.utils import ordered_load
def load_yaml(config_path):
with open(config_path, encoding='utf-8') as fp:
cfg = ordered_load(fp, yaml.SafeLoader)
return ObjDict(cfg)
class ConfigConstructor(object):
def __init__(self, config_path):
self.suffix2loadMethods = {'.yaml': load_yaml, '.yml': load_yaml}
self.inherit_tree = {}
self.config = self.load_config(config_path)
def load_config(self, config_path):
for suffix, m in self.suffix2loadMethods.items():
if suffix in config_path:
return ObjDict(m(config_path)).transform()
raise NotImplementedError
def config_inherit(self, base_config_path_list):
if isinstance(base_config_path_list, str):
base_config_path_list = [base_config_path_list]
base_config = ObjDict()
for base_cfg_path in base_config_path_list:
self.cfg_update(base_config, ConfigConstructor(base_cfg_path).get_config())
return base_config
def construct_config(self, config_dict, kwargs=None):
base_config = ObjDict()
for key, value in config_dict.items():
if key == '_Base_Config':
base_config = self.config_inherit(config_dict['_Base_Config'])
elif isinstance(value, container_abc.Mapping):
config_dict[key] = self.construct_config(value)
self.cfg_update(base_config, config_dict)
if kwargs is not None:
self.cfg_update(base_config, kwargs)
if '_Base_Config' in base_config:
base_config.pop('_Base_Config')
return base_config
def get_config(self, kwargs=None):
cfg = self.construct_config(self.config, kwargs)
return cfg
def update_by_type(self, base_value, new_value):
assert type(base_value) == type(new_value)
if isinstance(new_value, container_abc.Mapping):
base_value.update(new_value)
return base_value
if isinstance(base_value, list):
base_value.extend(new_value)
return base_value
raise NotImplemented
def cfg_update(self, base_cfg, new_cfg):
if not new_cfg:
base_cfg.clear()
add_key = set()
for key, value in new_cfg.items():
if key[-1] == '*':
ori_key = key[:-1]
if ori_key not in base_cfg:
continue
add_key.add(ori_key)
new_cfg[ori_key] = new_cfg[key]
new_cfg.pop(key)
for key, value in new_cfg.items():
if key not in base_cfg:
base_cfg[key] = value
elif isinstance(value, container_abc.Mapping):
if 'name' in value and value['name'] != base_cfg[key].get('name', None):
if value['name'][-1] != '*':
base_cfg[key] = new_cfg[key]
continue
value['name'] = value['name'][:-1]
self.cfg_update(base_cfg[key], new_cfg[key])
else:
if key in add_key:
base_cfg[key] = self.update_by_type(base_cfg[key], new_cfg[key])
else:
base_cfg[key] = new_cfg[key]