def _put(self, key_path, value, append=False): key_elt = key_path[0] if len(key_path) == 1: # if value to set does not exist, override # if they are both configs then merge # if not then override if key_elt in self and isinstance(self[key_elt], ConfigTree) and isinstance(value, ConfigTree): if self.root: new_value = ConfigTree.merge_configs(ConfigTree(), self[key_elt], copy_trees=True) new_value = ConfigTree.merge_configs(new_value, value, copy_trees=True) self._push_history(key_elt, new_value) self[key_elt] = new_value else: ConfigTree.merge_configs(self[key_elt], value) elif append: # If we have t=1 # and we try to put t.a=5 then t is replaced by {a: 5} l = self.get(key_elt, None) if isinstance(l, ConfigValues): l.tokens.append(value) l.recompute() elif isinstance(l, ConfigTree) and isinstance(value, ConfigValues): value.tokens.append(l) value.recompute() self._push_history(key_elt, value) self[key_elt] = value elif isinstance(l, list) and isinstance(value, ConfigValues): self._push_history(key_elt, value) self[key_elt] = value elif isinstance(l, list): l += value self._push_history(key_elt, l) elif l is None: self._push_history(key_elt, value) self[key_elt] = value else: raise ConfigWrongTypeException( u"Cannot concatenate the list {key}: {value} to {prev_value} of {type}".format( key='.'.join(key_path), value=value, prev_value=l, type=l.__class__.__name__) ) else: # if there was an override keep overide value if isinstance(value, ConfigValues): value.parent = self value.key = key_elt value.overriden_value = self.get(key_elt, None) self._push_history(key_elt, value) self[key_elt] = value else: next_config_tree = super(ConfigTree, self).get(key_elt) if not isinstance(next_config_tree, ConfigTree): # create a new dictionary or overwrite a previous value next_config_tree = ConfigTree() self._push_history(key_elt, value) self[key_elt] = next_config_tree next_config_tree._put(key_path[1:], value, append)
def _get(self, key_path, key_index=0, default=UndefinedKey): key_elt = key_path[key_index] elt = super(ConfigTree, self).get(key_elt, UndefinedKey) if elt is UndefinedKey: if default is UndefinedKey: raise ConfigMissingException( u"No configuration setting found for key {key}".format( key='.'.join(key_path[:key_index + 1]))) else: return default if key_index == len(key_path) - 1: if isinstance(elt, NoneValue): return None else: return elt elif isinstance(elt, ConfigTree): return elt._get(key_path, key_index + 1, default) else: if default is UndefinedKey: raise ConfigWrongTypeException( u"{key} has type {type} rather than dict".format( key='.'.join(key_path[:key_index + 1]), type=type(elt).__name__)) else: return default
def _put(self, key_path, value, append=False): key_elt = key_path[0] if len(key_path) == 1: # if value to set does not exist, override # if they are both configs then merge # if not then override if key_elt in self._dictionary and isinstance( self._dictionary[key_elt], ConfigTree) and isinstance( value, ConfigTree): self._merge_config_tree(self._dictionary[key_elt], value) elif append: l = self._dictionary.get(key_elt) if isinstance(l, list): l += value elif l is None: self._dictionary[key_elt] = value else: raise ConfigWrongTypeException( "Cannot concatenate the list {key}: {value} to {prev_value} of {type}" .format(key='.'.join(key_path), value=value, prev_value=l, type=l.__class__.__name__)) else: self._dictionary[key_elt] = value else: next_config_tree = self._dictionary.get(key_elt) if not isinstance(next_config_tree, ConfigTree): # create a new dictionary or overwrite a previous value next_config_tree = ConfigTree() self._dictionary[key_elt] = next_config_tree next_config_tree._put(key_path[1:], value, append)
def transform(self): def determine_type(token): return ConfigTree if isinstance( token, ConfigTree) else ConfigList if isinstance(token, list) else str def format_str(v): return '' if v is None else str(v) if self.has_substitution(): return self # remove None tokens tokens = [token for token in self.tokens if token is not None] if not tokens: return None # check if all tokens are compatible first_tok_type = determine_type(tokens[0]) for index, token in enumerate(tokens[1:]): tok_type = determine_type(token) if first_tok_type is not tok_type: raise ConfigWrongTypeException( "Token '{token}' of type {tok_type} (index {index}) must be of type {req_tok_type} (line: {line}, col: {col})" .format(token=token, index=index + 1, tok_type=tok_type.__name__, req_tok_type=first_tok_type.__name__, line=lineno(self._loc, self._instring), col=col(self._loc, self._instring))) if first_tok_type is ConfigTree: result = ConfigTree() for token in tokens: for key, val in token.items(): # update references for substituted contents if isinstance(val, ConfigValues): val.parent = result val.key = key result[key] = val return result elif first_tok_type is ConfigList: result = [] for sublist in tokens: sublist_result = ConfigList() for index, token in enumerate(sublist): if isinstance(token, ConfigValues): token.parent = result token.key = index sublist_result.append(token) result.extend(sublist_result) return [result] else: if len(tokens) == 1: return tokens[0] else: return ''.join( token if isinstance(token, str) else format_str(token) + ' ' for token in tokens[:-1]) + format_str(tokens[-1])
def transform(self): def determine_type(token): return ConfigTree if isinstance(token, ConfigTree) else ConfigList if isinstance(token, list) else str def format_str(v, last=False): if isinstance(v, ConfigQuotedString): return v.value + ('' if last else v.ws) else: return '' if v is None else str(v) if self.has_substitution(): return self # remove None tokens tokens = [token for token in self.tokens if token is not None] if not tokens: return None # check if all tokens are compatible first_tok_type = determine_type(tokens[0]) for index, token in enumerate(tokens[1:]): tok_type = determine_type(token) if first_tok_type is not tok_type: raise ConfigWrongTypeException( "Token '{token}' of type {tok_type} (index {index}) must be of type {req_tok_type} (line: {line}, col: {col})".format( token=token, index=index + 1, tok_type=tok_type.__name__, req_tok_type=first_tok_type.__name__, line=lineno(self._loc, self._instring), col=col(self._loc, self._instring))) if first_tok_type is ConfigTree: result = ConfigTree() for token in tokens: ConfigTree.merge_configs(result, token, copy_trees=True) return result elif first_tok_type is ConfigList: result = [] main_index = 0 for sublist in tokens: sublist_result = ConfigList() for token in sublist: if isinstance(token, ConfigValues): token.parent = result token.key = main_index main_index += 1 sublist_result.append(token) result.extend(sublist_result) return result else: if len(tokens) == 1: if isinstance(tokens[0], ConfigQuotedString): return tokens[0].value return tokens[0] else: return ''.join(format_str(token) for token in tokens[:-1]) + format_str(tokens[-1], True)
def _get(self, key_path, key_index=0): key_elt = key_path[key_index] elt = self._dictionary.get(key_elt) if elt is None: raise ConfigMissingException( "No configuration setting found for key {key}".format( key='.'.join(key_path[:key_index + 1]))) if key_index == len(key_path) - 1: return elt elif isinstance(elt, ConfigTree): return elt._get(key_path, key_index + 1) else: raise ConfigWrongTypeException( "{key} has type {type} rather than dict".format( key='.'.join(key_path[:key_index + 1]), type=type(elt).__name__))