Example #1
0
 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
Example #2
0
    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