def test_merge(): src = OrderedTree() src['a.b.c'] = 'foo' src['a.b.d'] = 'foo' print_yaml('src:', src) other = OrderedTree() other['x.y.z'] = 'foobar' print_yaml('other_tree:', other) src.merge(other) print_yaml("After updating x.y.z: ", src) assert 'a.b.c' in src assert 'a.b.d' in src assert 'x.y.z' in src assert src['a.b.d'] == 'foo' other['a.b.d.e'] = 'foobar' print_yaml('add a.b.d.e to other:', other) print_yaml('src:', src) src.merge(other) print_yaml("After merge: ", src) assert 'a.b.c' in src assert 'a.b.d' in src assert 'x.y.z' in src assert 'a.b.d.e' in src assert src['a.b.d'] != 'foo'
def test_merge_2(): src = OrderedTree() src['foo.bar.baz'] = 'boo boo' other = OrderedTree() other['x.y.z'] = 'xyz' other['foo.bar.soo'] = 'moo moo' # other['foo.bar.baz.too'] = 'moo moo' src.merge(other) print_yaml("add merge src and other", src) src.merge(other) print_yaml("add merge src and other", src)
def test_merge_dict_objects(): tree = OrderedTree() tree['foo'] = 'foo' tree['bar'] = 'baz' obj = { "test": "foo", "foo": "bar" } tree.merge(obj) print_yaml("updating a simple dict", tree) assert 'test' in tree assert 'foo' in tree assert isinstance(tree['foo'], OrderedTree) is False assert tree['test'] == 'foo' assert tree['foo'] == 'bar' assert tree['bar'] == 'baz' # add to existing tree replace_bar = { "bar": { "baz": { "boo": "baaaad" } } } tree.merge(replace_bar) print_yaml("replace bar with a dict", tree) assert 'test' in tree assert 'foo' in tree assert 'bar' in tree assert isinstance(tree['foo'], OrderedTree) is False assert isinstance(tree['bar'], OrderedTree) assert tree['test'] == 'foo' assert tree['foo'] == 'bar' assert tree['bar.baz.boo'] == 'baaaad' assert isinstance(tree['bar.baz'], OrderedTree) # add more values to the existing dictionary add_to_bar = { "bar": { "too": { "moo": "yo yo" } } } tree.merge(add_to_bar) print_yaml("replace bar with a dict", tree) assert 'test' in tree assert 'foo' in tree assert 'bar' in tree assert isinstance(tree['foo'], OrderedTree) is False assert isinstance(tree['bar'], OrderedTree) assert tree['test'] == 'foo' assert tree['foo'] == 'bar' assert tree['bar.baz.boo'] == 'baaaad' assert isinstance(tree['bar.baz'], OrderedTree) assert tree['bar.too.moo'] == 'yo yo' assert isinstance(tree['bar.too'], OrderedTree)
class Loader(object): def __init__(self, config_dir, settings): self._settings = settings self._config_dir = config_dir self._loaded = False self._all_settings = None self._file_list = None self._invalid_paths = None self._all_settings = OrderedTree('!') def settings(self): self.load() LookupDirective.lookup_table = self._all_settings return self._all_settings def load_file(self, f): self.load() cfg = load_configuration(f, self._config_dir) self._all_settings.merge(cfg) def merge(self, tree): self._all_settings.merge(tree) def load(self): if self._loaded: return self._file_list = [] self._invalid_paths = [] self._create_file_list(self._settings, self._file_list) logger.info( "\nList of files to load :\n - %s", '\n - '.join([ x[len(self._config_dir) + 1:] for x in self._file_list ])) if self._invalid_paths: logger.info("invalid files :\n %s", '\n'.join(self._invalid_paths)) raise OptionError(self._invalid_paths) all_cfg = Configuration.from_dict({}) for f in self._file_list: cfg = load_configuration(f, self._config_dir) try: del cfg[DEFAULTS_TAG] except KeyError: pass else: logger.debug("Successfully removed default traces from %s" % f) all_cfg.merge(cfg) self._all_settings.merge(all_cfg) self._loaded = True def _create_file_list(self, settings, file_list, parent_path=""): """ Appends list of files to be process to self._file_list and list of invalid file paths to self._invalid_paths """ logger.debug('settings:\n %s \n parent: %s \n files: %s', settings, parent_path, file_list) for key, sub_tree in settings.items(): # ignore the special key value if key == VALUES_KEY: continue logger.debug("key: %s, subtree: %s", key, sub_tree) path = "%(parent_path)s%(key)s%(sep)s%(file)s" % { 'parent_path': parent_path, 'key': key, 'sep': os.sep, 'file': sub_tree[VALUES_KEY] } abs_file_path = os.path.abspath( self._config_dir + os.sep + path + '.yml') file_list.append(abs_file_path) logger.debug('path: %s', abs_file_path) if not os.path.exists(abs_file_path): self._invalid_paths.append(abs_file_path) # recurse if there are sub settings if (isinstance(sub_tree, dict) and len(sub_tree.keys()) > 1): logger.debug('recursing into: sub-tree: %s', sub_tree) self._create_file_list(sub_tree, file_list, path + os.sep)
class Loader(object): def __init__(self, config_dir, settings): self._settings = settings self._config_dir = config_dir self._loaded = False self._all_settings = None self._file_list = None self._invalid_paths = None self._all_settings = OrderedTree('!') def settings(self): self.load() LookupDirective.lookup_table = self._all_settings return self._all_settings def load_file(self, f): self.load() cfg = load_configuration(f, self._config_dir) self._all_settings.merge(cfg) def merge(self, tree): self._all_settings.merge(tree) def load(self): if self._loaded: return self._file_list = [] self._invalid_paths = [] self._create_file_list(self._settings, self._file_list) logger.info( "\nList of files to load :\n - %s", '\n - '.join( [x[len(self._config_dir) + 1:] for x in self._file_list])) if self._invalid_paths: logger.info("invalid files :\n %s", '\n'.join(self._invalid_paths)) raise OptionError(self._invalid_paths) all_cfg = Configuration.from_dict({}) for f in self._file_list: cfg = load_configuration(f, self._config_dir) try: del cfg[DEFAULTS_TAG] except KeyError: pass else: logger.debug("Successfully removed default traces from %s" % f) all_cfg.merge(cfg) self._all_settings.merge(all_cfg) self._loaded = True def _create_file_list(self, settings, file_list, parent_path=""): """ Appends list of files to be process to self._file_list and list of invalid file paths to self._invalid_paths """ logger.debug('settings:\n %s \n parent: %s \n files: %s', settings, parent_path, file_list) for key, sub_tree in settings.items(): # ignore the special key value if key == VALUES_KEY: continue logger.debug("key: %s, subtree: %s", key, sub_tree) path = "%(parent_path)s%(key)s%(sep)s%(file)s" % { 'parent_path': parent_path, 'key': key, 'sep': os.sep, 'file': sub_tree[VALUES_KEY] } abs_file_path = os.path.abspath(self._config_dir + os.sep + path + '.yml') file_list.append(abs_file_path) logger.debug('path: %s', abs_file_path) if not os.path.exists(abs_file_path): self._invalid_paths.append(abs_file_path) # recurse if there are sub settings if (isinstance(sub_tree, dict) and len(sub_tree.keys()) > 1): logger.debug('recursing into: sub-tree: %s', sub_tree) self._create_file_list(sub_tree, file_list, path + os.sep)