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))
def test_new_subpath(self): l = ['a', 'b', 'c'] p = DictPath(':', l[:-1]) p = p.new_subpath(l[-1]) self.assertListEqual(p.path, l)
def test_new_subpath(self): l = ['a', 'b', 'c'] p = DictPath(':', l[:-1]) p = p.new_subpath(l[-1]) self.assertListEqual(p.path, l)
def test_new_subpath(self): l = ["a", "b", "c"] p = DictPath(":", l[:-1]) p = p.new_subpath(l[-1]) self.assertListEqual(p.path, l)