Skip to content

Instantly share code, notes, and snippets.

@hemebond
Last active March 13, 2016 10:42
Show Gist options
  • Save hemebond/623f0cc1f14392d62d89 to your computer and use it in GitHub Desktop.
Save hemebond/623f0cc1f14392d62d89 to your computer and use it in GitHub Desktop.
Additional method on the SaltYamlSafeLoader class in yamlloader.py to fix YAML merging
class SaltYamlSafeLoader(yaml.SafeLoader, object):
def flatten_mapping(self, node):
merge = []
index = 0
while index < len(node.value):
key_node, value_node = node.value[index]
if key_node.tag == u'tag:yaml.org,2002:merge':
del node.value[index]
if isinstance(value_node, MappingNode):
self.flatten_mapping(value_node)
merge.extend(value_node.value)
elif isinstance(value_node, SequenceNode):
submerge = []
for subnode in value_node.value:
if not isinstance(subnode, MappingNode):
raise ConstructorError("while constructing a mapping",
node.start_mark,
"expected a mapping for merging, but found %s"
% subnode.id, subnode.start_mark)
self.flatten_mapping(subnode)
submerge.append(subnode.value)
submerge.reverse()
for value in submerge:
merge.extend(value)
else:
raise ConstructorError("while constructing a mapping", node.start_mark,
"expected a mapping or list of mappings for merging, but found %s"
% value_node.id, value_node.start_mark)
elif key_node.tag == u'tag:yaml.org,2002:value':
key_node.tag = u'tag:yaml.org,2002:str'
index += 1
else:
index += 1
if merge:
# Here we need to discard any duplicate entries based on key_node
existing_nodes = [name_node.value for name_node, value_node in node.value]
mergeable_items = [x for x in merge if x[0].value not in existing_nodes]
node.value = mergeable_items + node.value
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment