def _try_parse_data(self, node, piece): """Using the format in the given node, try to parse the given piece and re-acquire the data that created it originally. @return True on parse-success, False on failure. @param node a `StringFormatNode` compatible node @param piece a string which was previously returned by `iterate_consumption_candidates` """ try: result = parse.parse(node.format_string(), piece, re_flags=0) if result is None: return False if result.fixed: raise ValueError("Format shouldn't have fixed arguments") #end make assertion except ValueError: self.log.error("Ignored format as it could not be parsed: '%s'" % node.format_string(), exc_info=True) return False #end handle exceptions # put keys into our data - its okay to have no keys, not all formats have them if result.named: kvstore = UnorderedKeyValueStoreModifier(self._parsed_data) for nested_key, value in result.named.iteritems(): kvstore.set_value(nested_key, value) #end for each key to store # kvstore copies the data, therefore we have to get it back - its somewhat inefficient, but good # enough for now. Could use the private API, _data(), to get a reference, but lets not go there. self._parsed_data = kvstore.data() #end fill data dict by keys return True
def _apply_format(self, data, index=None): """@return a string which is the result of the substitution @param data see the `format()` method @param index a dict that will be used similarly to the `validate()` method of the `ValidatedElementNode` to track format errors (which can only be cought when actually applying the format). If None, these issues will not be recorded. @return a new string with all substitutions applied successfully, or None string if there was insufficient data or if we didn't have the format attribute. And a (nested) data dictionary instance which contains all the data strings actually used. It will be empty if there was no format. """ # determine if all named fields are actually available in data invalid = (None, dict()) if not self._has_required_keys(data): return invalid # end msg = None try: assert self.format_string(), "node '%s': Format should not be empty" % self.key() res = self.format_string().format(**data) # still here ? Store the data we actually used kvmod = UnorderedKeyValueStoreModifier(dict()) kvprovider = RelaxedKeyValueStoreProvider(DictObject(data).to_dict(recursive=True)) for key in self.format_keys(): kvmod.set_value(key, kvprovider.value(key, dict())) # end for each key return res, kvmod.data() except KeyError: # apparently, someone used an alternate form, otherwise the _has_required_keys would have cought this msg = "Use the dot-separated form to access members, not the dict one, in format '%s'" % self.format_string() self.log.error(msg, exc_info=True) except Exception: # catch all - this is a serious issue though msg = "Failed to apply format '%s'" % self.format_string() self.log.error(msg, exc_info=True) # end handle insufficient data for format if msg and index: index[self._to_fq_meta_key('format')] = msg # end keep track of issues return invalid