def add_src(self, src, conf, filter_none=False, fallback=False): """ Add a source of configuration. :param src: Name of the soruce to add :type src: str :param conf: Nested mapping of key/values to overlay :type conf: collections.abc.Mapping :param filter_none: Ignores the keys that have a ``None`` value. That simplifies the creation of the mapping, by having keys always present. That should not be used if ``None`` value for a key is expected, as opposit to not having that key set at all. :type filter_none: bool :param fallback: If True, the source will be added as a fallback, which means at the end of the priority list. By default, the source will have the highest priority and will be used unless a key-specific priority override is setup. :type fallback: bool This method provides a way to update the configuration, by importing a mapping as a new source. """ logger = self.get_logger() if logger.isEnabledFor(logging.DEBUG): caller, filename, lineno = get_call_site( 1, exclude_caller_module=True) logger.debug( '{caller} ({filename}:{lineno}) has set source "{src}":\n{conf}' .format( src=src, conf=conf, caller=caller if caller else '<unknown>', filename=filename if filename else '<unknown>', lineno=lineno if lineno else '<unknown>', )) return self._add_src(src, conf, filter_none=filter_none, fallback=fallback)
def get_key(self, key, src=None, eval_deferred=True, quiet=False): """ Get the value of the given key. It returns a deepcopy of the value. :param key: name of the key to lookup :type key: str :param src: If not None, look up the value of the key in that source :type src: str or None :param eval_deferred: If True, evaluate instances of :class:`DeferredValue` if needed :type eval_deferred: bool :param quiet: Avoid logging the access :type quiet: bool .. note:: Using the indexing operator ``self[key]`` is preferable in most cases , but this method provides more parameters. """ key_desc = self._structure[key] if isinstance(key_desc, LevelKeyDesc): return self._sublevel_map[key] elif isinstance(key_desc, DerivedKeyDesc): # Specifying a source is an error for a derived key if src is not None: key = key_desc.qualname raise ValueError( 'Cannot specify the source when getting "{key}" since it is a derived key' .format( key=key, src=src, ), key) val = key_desc.compute_val(self) src = self.resolve_src(key) else: # Compute the source to use for that key if src is None: src = self.resolve_src(key) try: val = self._key_map[key][src] except KeyError: key = key_desc.qualname raise KeyError( 'Key "{key}" is not available from source "{src}"'.format( key=key, src=src, ), key) if eval_deferred: val = self._eval_deferred_val(src, key) logger = self.get_logger() if not quiet and logger.isEnabledFor(logging.DEBUG): caller, filename, lineno = get_call_site( 2, exclude_caller_module=True) logger.debug( '{caller} ({filename}:{lineno}) has used key {key} from source "{src}": {val}' .format( key=key_desc.qualname, src=src, val=key_desc.pretty_format(val), caller=caller if caller else '<unknown>', filename=filename if filename else '<unknown>', lineno=lineno if lineno else '<unknown>', )) if isinstance(val, DeferredValue): return val else: return copy.deepcopy(val)