Пример #1
0
 def test_set_value_escaped(self):
     v = 42
     l = ['a', 'b:b', 'c']
     d = {'a':{'b:b':{'c':v}}}
     p = DictPath(':', l)
     p.set_value(d, v+1)
     self.assertEqual(d['a']['b:b']['c'], v+1)
Пример #2
0
 def test_set_value_escaped_listindex_list(self):
     v = 42
     l = ["a", 1, "c"]
     d = {"a": [None, {"c": v}, None]}
     p = DictPath(":", l)
     p.set_value(d, v + 1)
     self.assertEqual(d["a"][1]["c"], v + 1)
Пример #3
0
 def test_set_value_escaped_listindex_str(self):
     v = 42
     s = "a:1:c"
     d = {"a": [None, {"c": v}, None]}
     p = DictPath(":", s)
     p.set_value(d, v + 1)
     self.assertEqual(d["a"][1]["c"], v + 1)
Пример #4
0
 def test_set_value_escaped_listindex_list(self):
     v = 42
     l = ['a', 1, 'c']
     d = {'a':[None, {'c':v}, None]}
     p = DictPath(':', l)
     p.set_value(d, v+1)
     self.assertEqual(d['a'][1]['c'], v+1)
Пример #5
0
 def test_set_value_escaped(self):
     v = 42
     l = ["a", "b:b", "c"]
     d = {"a": {"b:b": {"c": v}}}
     p = DictPath(":", l)
     p.set_value(d, v + 1)
     self.assertEqual(d["a"]["b:b"]["c"], v + 1)
Пример #6
0
 def test_set_value_escaped_listindex_list(self):
     v = 42
     l = ['a', 1, 'c']
     d = {'a': [None, {'c': v}, None]}
     p = DictPath(':', l)
     p.set_value(d, v + 1)
     self.assertEqual(d['a'][1]['c'], v + 1)
Пример #7
0
 def test_set_value_escaped_listindex_str(self):
     v = 42
     s = 'a:1:c'
     d = {'a':[None, {'c':v}, None]}
     p = DictPath(':', s)
     p.set_value(d, v+1)
     self.assertEqual(d['a'][1]['c'], v+1)
Пример #8
0
 def test_set_value_escaped(self):
     v = 42
     l = ['a', 'b:b', 'c']
     d = {'a': {'b:b': {'c': v}}}
     p = DictPath(':', l)
     p.set_value(d, v + 1)
     self.assertEqual(d['a']['b:b']['c'], v + 1)
Пример #9
0
 def test_set_value_escaped_listindex_str(self):
     v = 42
     s = 'a:1:c'
     d = {'a': [None, {'c': v}, None]}
     p = DictPath(':', s)
     p.set_value(d, v + 1)
     self.assertEqual(d['a'][1]['c'], v + 1)
Пример #10
0
 def test_equality(self):
     delim = ':'
     s = 'a{0}b{0}c'.format(delim)
     l = ['a', 'b', 'c']
     p1 = DictPath(delim, s)
     p2 = DictPath(delim, l)
     self.assertEqual(p1, p2)
Пример #11
0
 def test_inequality_content(self):
     delim = ':'
     s = 'a{0}b{0}c'.format(delim)
     l = ['d', 'e', 'f']
     p1 = DictPath(delim, s)
     p2 = DictPath(delim, l)
     self.assertNotEqual(p1, p2)
Пример #12
0
    def merge(self, other):
        """Merge function (public edition).

        Call _merge_recurse on self with either another Parameter object or a
        dict (for initialization). Set initmerge if it's a dict.

        Args:
            other (dict or Parameter): Thing to merge with self._base

        Returns:
            None: Nothing

        """

        self._unrendered = None
        if isinstance(other, dict):
            wrapped = self._wrap_dict(other,
                                      DictPath(self._settings.delimiter))
        elif isinstance(other, self.__class__):
            wrapped = self._wrap_dict(other._base,
                                      DictPath(self._settings.delimiter))
        else:
            raise TypeError('Cannot merge %s objects into %s' %
                            (type(other), self.__class__.__name__))
        self._base = self._merge_recurse(self._base, wrapped,
                                         DictPath(self._settings.delimiter))
Пример #13
0
 def _value_expression(self, inventory):
     results = {}
     path = DictPath(self._delimiter, self._expr[0][1]).drop_first()
     for node, items in inventory.iteritems():
         if path.exists_in(items):
             results[node] = copy.deepcopy(self._resolve(path, items))
     return results
Пример #14
0
 def _get_required_paths(self, mainpath):
     paths = {}
     path = DictPath(self._settings.delimiter)
     for i in mainpath.key_parts():
         path.add_subpath(i)
         if path in self._unrendered:
             paths[path] = True
     for i in self._unrendered:
         if mainpath.is_ancestor_of(i) or mainpath == i:
             paths[i] = True
     return paths
Пример #15
0
    def _merge_recurse(self, cur, new, path=None, initmerge=False):
        """Merge a parameter with another parameter.

        Iterate over keys in new. Call _merge_dict, _extend_list, or
        _update_scalar depending on type. Pass along whether this is an
        initialization merge.

        Args:
            cur (dict): Current dictionary
            new (dict): Dictionary to be merged
            path (string): Merging path from recursion
            initmerge (bool): True if called as part of entity init, defaults
                to False

        Returns:
            dict: a merged dictionary

        """

        if path is None:
            path = DictPath(self.delimiter)

        if isinstance(new, dict):
            if cur is None:
                cur = {}
            return self._merge_dict(cur, new, path, initmerge)

        elif isinstance(new, list):
            if cur is None:
                cur = []
            return self._extend_list(cur, new, path)

        else:
            return self._update_scalar(cur, new, path)
Пример #16
0
 def _initialise_interpolate(self):
     if self._unrendered is None:
         self._unrendered = {}
         self._inv_queries = []
         self._needs_all_envs = False
         self._resolve_errors = ResolveErrorList()
         self._render_simple_dict(self._base,
                                  DictPath(self._settings.delimiter))
Пример #17
0
 def _get_vars(self, var, export, parameter, value):
     if isinstance(var, str):
         path = DictPath(self._delimiter, var)
         if path.path[0].lower() == 'exports':
             export = path
         elif path.path[0].lower() == 'self':
             parameter = path
         else:
             value = var
     else:
         value = var
     return export, parameter, value
Пример #18
0
    def _interpolate_references(self, path, value, inventory):
        all_refs = False
        while not all_refs:
            for ref in value.get_references():
                path_from_ref = DictPath(self._delimiter, ref)

                if path_from_ref in self._unrendered:
                    if self._unrendered[path_from_ref] is False:
                        # every call to _interpolate_inner replaces the value of
                        # self._unrendered[path] with False
                        # Therefore, if we encounter False instead of True,
                        # it means that we have already processed it and are now
                        # faced with a cyclical reference.
                        raise InfiniteRecursionError(path, ref)
                    else:
                        self._interpolate_inner(path_from_ref, inventory)
                else:
                    # ensure ancestor keys are already dereferenced
                    ancestor = DictPath(self._delimiter)
                    for k in path_from_ref.key_parts():
                        ancestor = ancestor.new_subpath(k)
                        if ancestor in self._unrendered:
                            self._interpolate_inner(ancestor, inventory)
            if value.allRefs():
                all_refs = True
            else:
                # not all references in the value could be calculated previously so
                # try recalculating references with current context and recursively
                # call _interpolate_inner if the number of references has increased
                # Otherwise raise an error
                old = len(value.get_references())
                value.assembleRefs(self._base)
                if old == len(value.get_references()):
                    raise InterpolationError('Bad reference count, path:' +
                                             repr(path))
Пример #19
0
    def _parse_expression(self, expr):
        parser = parser_funcs.get_expression_parser()
        try:
            tokens = parser.parseString(expr).asList()
        except pp.ParseException as e:
            raise ParseError(e.msg, e.line, e.col, e.lineno)

        if len(tokens) == 2:  # options are set
            passed_opts = [x[1] for x in tokens.pop(0)]
            self.ignore_failed_render = parser_funcs.IGNORE_ERRORS in passed_opts
            self.needs_all_envs = parser_funcs.ALL_ENVS in passed_opts
        elif len(tokens) > 2:
            raise ExpressionError('Failed to parse %s' % str(tokens),
                                  tbFlag=False)
        self._expr_type = tokens[0][0]
        self._expr = list(tokens[0][1])

        if self._expr_type == parser_funcs.VALUE:
            self._value_path = DictPath(self._settings.delimiter,
                                        self._expr[0][1]).drop_first()
            self._question = LogicTest([], self._settings.delimiter)
            self.refs = []
            self.inv_refs = [self._value_path]
        elif self._expr_type == parser_funcs.TEST:
            self._value_path = DictPath(self._settings.delimiter,
                                        self._expr[0][1]).drop_first()
            self._question = LogicTest(self._expr[2:],
                                       self._settings.delimiter)
            self.refs = self._question.refs
            self.inv_refs = self._question.inv_refs
            self.inv_refs.append(self._value_path)
        elif self._expr_type == parser_funcs.LIST_TEST:
            self._value_path = None
            self._question = LogicTest(self._expr[1:],
                                       self._settings.delimiter)
            self.refs = self._question.refs
            self.inv_refs = self._question.inv_refs
        else:
            msg = 'Unknown expression type: %s'
            raise ExpressionError(msg % self._expr_type, tbFlag=False)
Пример #20
0
    def _parse_expression(self, expr):
        try:
            tokens = InvItem._parser.parseString(expr).asList()
        except pp.ParseException as e:
            raise ParseError(e.msg, e.line, e.col, e.lineno)

        if len(tokens) == 1:
            self._expr_type = tokens[0][0]
            self._expr = list(tokens[0][1])
        elif len(tokens) == 2:
            for opt in tokens[0]:
                if opt[1] == _IGNORE_ERRORS:
                    self._ignore_failed_render = True
                elif opt[1] == _ALL_ENVS:
                    self._needs_all_envs = True
            self._expr_type = tokens[1][0]
            self._expr = list(tokens[1][1])
        else:
            raise ExpressionError('Failed to parse %s' % str(tokens), tbFlag=False)

        if self._expr_type == _VALUE:
            self._value_path = DictPath(self._settings.delimiter, self._expr[0][1]).drop_first()
            self._question = Question([], self._settings.delimiter)
            self._refs = []
            self._inv_refs = [ self._value_path ]
        elif self._expr_type == _TEST:
            self._value_path = DictPath(self._settings.delimiter, self._expr[0][1]).drop_first()
            self._question = Question(self._expr[2:], self._settings.delimiter)
            self._refs = self._question.refs()
            self._inv_refs = self._question.inv_refs()
            self._inv_refs.append(self._value_path)
        elif self._expr_type == _LIST_TEST:
            self._value_path = None
            self._question = Question(self._expr[1:], self._settings.delimiter)
            self._refs = self._question.refs()
            self._inv_refs = self._question.inv_refs()
        else:
            raise ExpressionError('Unknown expression type: %s' % self._expr_type, tbFlag=False)
Пример #21
0
    def _test_expression(self, context, inventory):
        export_path = None
        parameter_path = None
        parameter_value = None
        test = None
        value_path = DictPath(self._delimiter, self._expr[0][1])

        if self._expr[3][1] == _EQUAL:
            test = _EQUAL
        elif self._expr[3][1] == _NOT_EQUAL:
            test = _NOT_EQUAL

        export_path, parameter_path, parameter_value = self._get_vars(self._expr[2][1], export_path, parameter_path, parameter_value)
        export_path, parameter_path, parameter_value = self._get_vars(self._expr[4][1], export_path, parameter_path, parameter_value)

        if parameter_path is not None:
            parameter_path.drop_first()
            parameter_value = self._resolve(parameter_path, context)

        if export_path is None or parameter_value is None or test is None or value_path is None:
            ExpressionError('Failed to render %s' % str(self))

        export_path.drop_first()
        value_path.drop_first()

        results = {}
        for node, items in inventory.iteritems():
            if export_path.exists_in(items):
                export_value = self._resolve(export_path, items)
                test_passed = False
                if test == _EQUAL and export_value == parameter_value:
                    test_passed = True
                elif test == _NOT_EQUAL and export_value != parameter_value:
                    test_passed = True
                if test_passed:
                    results[node] = copy.deepcopy(self._resolve(value_path, items))
        return results
Пример #22
0
 def _wrap_value(self, value):
     if isinstance(value, (Value, ValueList)):
         return value
     elif isinstance(value, dict):
         return self._wrap_dict(value)
     elif isinstance(value, list):
         return self._wrap_list(value)
     else:
         try:
             return Value(value,
                          self._settings,
                          self._uri,
                          parse_string=self._parse_strings)
         except InterpolationError as e:
             e.context = DictPath(self._settings.delimiter)
             raise
Пример #23
0
 def _get_vars(self, var, export=None, parameter=None, value=None):
     if isinstance(var, string_types):
         path = DictPath(self._delimiter, var)
         if path.path[0].lower() == 'exports':
             export = path
         elif path.path[0].lower() == 'self':
             parameter = path
         elif path.path[0].lower() == 'true':
             value = True
         elif path.path[0].lower() == 'false':
             value = False
         else:
             value = var
     else:
         value = var
     return export, parameter, value
Пример #24
0
    def _merge_recurse(self, cur, new, path=None):
        if path is None:
            path = DictPath(self.delimiter)

        if isinstance(new, dict):
            if cur is None:
                cur = {}
            return self._merge_dict(cur, new, path)

        elif isinstance(new, list):
            if cur is None:
                cur = []
            return self._extend_list(cur, new, path)

        else:
            return self._update_scalar(cur, new, path)
Пример #25
0
    def _interpolate_inner(self, path, refvalue):
        self._occurrences[path] = True  # mark as seen
        for ref in refvalue.get_references():
            path_from_ref = DictPath(self.delimiter, ref)
            try:
                refvalue_inner = self._occurrences[path_from_ref]

                # If there is no reference, then this will throw a KeyError,
                # look further down where this is caught and execution passed
                # to the next iteration of the loop
                #
                # If we get here, then the ref references another parameter,
                # requiring us to recurse, dereferencing first those refs that
                # are most used and are thus at the leaves of the dependency
                # tree.

                if refvalue_inner is True:
                    # every call to _interpolate_inner replaces the value of
                    # the saved occurrences of a reference with True.
                    # Therefore, if we encounter True instead of a refvalue,
                    # it means that we have already processed it and are now
                    # faced with a cyclical reference.
                    raise InfiniteRecursionError(path, ref)
                self._interpolate_inner(path_from_ref, refvalue_inner)

            except KeyError as e:
                # not actually an error, but we are done resolving all
                # dependencies of the current ref, so move on
                continue

        try:
            new = refvalue.render(self._base)
            path.set_value(self._base, new)

            # finally, remove the reference from the occurrences cache
            del self._occurrences[path]
        except UndefinedVariableError as e:
            raise UndefinedVariableError(e.var, path)
Пример #26
0
 def test_inequality_delimiter(self):
     l = ['a', 'b', 'c']
     p1 = DictPath(':', l)
     p2 = DictPath('%', l)
     self.assertNotEqual(p1, p2)
Пример #27
0
 def test_new_subpath(self):
     l = ["a", "b", "c"]
     p = DictPath(":", l[:-1])
     p = p.new_subpath(l[-1])
     self.assertListEqual(p.path, l)
Пример #28
0
 def test_get_value_listindex_str(self):
     v = 42
     s = 'a:1:c'
     d = {'a':[None, {'c':v}, None]}
     p = DictPath(':', s)
     self.assertEqual(p.get_value(d), v)
Пример #29
0
 def test_constructor_invalid_type(self):
     with self.assertRaises(TypeError):
         p = DictPath(':', 5)
Пример #30
0
 def test_get_value_listindex_str(self):
     v = 42
     s = "a:1:c"
     d = {"a": [None, {"c": v}, None]}
     p = DictPath(":", s)
     self.assertEqual(p.get_value(d), v)
Пример #31
0
 def test_get_value_escaped(self):
     v = 42
     l = ['a', 'b:b', 'c']
     d = {'a': {'b:b': {'c': v}}}
     p = DictPath(':', l)
     self.assertEqual(p.get_value(d), v)
Пример #32
0
 def test_path_accessor(self):
     l = ['a', 'b', 'c']
     p = DictPath(':', l)
     self.assertListEqual(p.path, l)
Пример #33
0
 def test_get_value_listindex_list(self):
     v = 42
     l = ["a", 1, "c"]
     d = {"a": [None, {"c": v}, None]}
     p = DictPath(":", l)
     self.assertEqual(p.get_value(d), v)
Пример #34
0
 def resolve(self, context, *args, **kwargs):
     path = DictPath(kwargs['delim'], self.string)
     try:
         return path.get_value(context)
     except KeyError as e:
         raise UndefinedVariableError(self.string)
Пример #35
0
 def test_set_nonexistent_value(self):
     l = ["a", "d"]
     p = DictPath(":", l)
     with self.assertRaises(KeyError):
         p.set_value(dict(), 42)
Пример #36
0
 def test_get_value_listindex_list(self):
     v = 42
     l = ['a', 1, 'c']
     d = {'a':[None, {'c':v}, None]}
     p = DictPath(':', l)
     self.assertEqual(p.get_value(d), v)
Пример #37
0
 def test_get_value_escaped(self):
     v = 42
     l = ['a', 'b:b', 'c']
     d = {'a':{'b:b':{'c':v}}}
     p = DictPath(':', l)
     self.assertEqual(p.get_value(d), v)
Пример #38
0
 def test_repr(self):
     delim = '%'
     s = 'a:b\:b:c'
     p = DictPath(delim, s)
     self.assertEqual('%r' % p, 'DictPath(%r, %r)' % (delim, s))
Пример #39
0
 def test_str(self):
     s = 'a:b\:b:c'
     p = DictPath(':', s)
     self.assertEqual(str(p), s)
Пример #40
0
 def test_set_nonexistent_value(self):
     l = ['a', 'd']
     p = DictPath(':', l)
     with self.assertRaises(KeyError):
         p.set_value(dict(), 42)
Пример #41
0
 def test_new_subpath(self):
     l = ['a', 'b', 'c']
     p = DictPath(':', l[:-1])
     p = p.new_subpath(l[-1])
     self.assertListEqual(p.path, l)
Пример #42
0
 def test_constructor_list(self):
     l = ['a', 'b', 'c']
     p = DictPath(':', l)
     self.assertListEqual(p._parts, l)
Пример #43
0
 def test_get_value_listindex_list(self):
     v = 42
     l = ['a', 1, 'c']
     d = {'a': [None, {'c': v}, None]}
     p = DictPath(':', l)
     self.assertEqual(p.get_value(d), v)
Пример #44
0
 def test_constructor_str_escaped(self):
     delim = ':'
     s = 'a{0}b\{0}b{0}c'.format(delim)
     l = ['a', 'b\\{0}b'.format(delim), 'c']
     p = DictPath(delim, s)
     self.assertListEqual(p._parts, l)
Пример #45
0
 def test_set_nonexistent_value(self):
     l = ['a', 'd']
     p = DictPath(':', l)
     with self.assertRaises(KeyError):
         p.set_value(dict(), 42)
Пример #46
0
 def test_get_value_escaped(self):
     v = 42
     l = ["a", "b:b", "c"]
     d = {"a": {"b:b": {"c": v}}}
     p = DictPath(":", l)
     self.assertEqual(p.get_value(d), v)
Пример #47
0
 def _resolve(self, ref, context):
     path = DictPath(self._delim, ref)
     try:
         return path.get_value(context)
     except KeyError as e:
         raise UndefinedVariableError(ref)
Пример #48
0
 def test_new_subpath(self):
     l = ['a', 'b', 'c']
     p = DictPath(':', l[:-1])
     p = p.new_subpath(l[-1])
     self.assertListEqual(p.path, l)