If you want to create something like that, at least in ruamel.yaml ¹, you should use round-trip mode, which also preserves the merges. The following doesn't throw an assertion error:
import ruamel.yaml
yaml_str = """\
foo: &xyz
a: 42
bar:
<<: *xyz
"""
data = ruamel.yaml.round_trip_load(yaml_str)
assert ruamel.yaml.round_trip_dump(data) == yaml_str
What this means is that data
has enough information to recreate the merge as it was in the output. In practise however, in round-trip mode, the merge never takes place. Instead retrieving a value data['foo']['bar']['a']
means that there is no real key 'bar'
in data['foo']
, but that that key is subsequently looked up in the attached "merge mappings".
There is no public interface for this (so things might change), but by analyzing data
and looking at ruamel.yaml.comments.CommentedMap()
you can find that there is a merge_attrib
(currently being the string _yaml_merge
) and more useful that there is a method add_yaml_merge()
. The latter takes a list of (int, CommentedMap()) tuples.
baz = ruamel.yaml.comments.CommentedMap()
baz['b'] = 196
baz.yaml_set_anchor('klm')
data.insert(1, 'baz', baz)
you need to insert the 'baz'
key before the 'bar'
key of data, otherwise the mapping will reverse. After insert the new structure in the merge for data['bar']
:
data['bar'].add_yaml_merge([(0, baz)])
ruamel.yaml.round_trip_dump(data, sys.stdout)
which gives:
foo: &xyz
a: 42
baz: &klm
b: 196
bar:
<<: [*xyz, *klm]
( if you like to see what add_yaml_merge
does insert
print(getattr(data['bar'], ruamel.yaml.comments.merge_attrib))
before and after the call)
If you want to start from scratch completely you can do:
data = ruamel.yaml.comments.CommentedMap([
('foo', ruamel.yaml.comments.CommentedMap([('a', 42)])),
])
data['foo'].yaml_set_anchor('xyz')
data['bar'] = bar = ruamel.yaml.comments.CommentedMap()
bar.add_yaml_merge([(0, data['foo'])])
instead of the data = ruamel.yaml.round_trip_load(yaml_str)
.
¹ Disclaimer: I am the author of that package.
d = ruamel.yaml.round_trip_load(ruamel.yaml.dump(data))
to import adict
into around_trip
object? – Kiwi