Reputation: 189786
I have a plain data structure that I need to dump into a YAML file and add a type tag at the beginning with a !v2
line.
How do I do that with the PyYAML library?
import yaml
class MyDumper(yaml.SafeDumper):
# ???
# somehow add a "!v2" type tag at the beginning
y = {'foo': 3, 'bar': 'haha', 'baz': [1,2,3]}
with open(myfile, 'w') as f:
# a hack would be to write the "!v2" here,
# outside the normal yaml.dump process,
# but I'd like to learn the right way
yaml.dump(f, y, Dumper=MyDumper)
Upvotes: 1
Views: 757
Reputation: 76682
If I read your !v2
addition correctly this is essentially a tag for the top-level dictionary (and thereby implicit for the whole file). In order to write that out with a tag correctly make that top-level dict into separate type (subclassed from dict) and create a type specific dumper:
import ruamel.yaml as yaml
from ruamel.yaml.representer import RoundTripRepresenter
class VersionedDict(dict):
pass
y = VersionedDict(foo=3, bar='haha', baz=[1,2,3])
def vdict_representer(dumper, data):
return dumper.represent_mapping('!v2', dict(data))
RoundTripRepresenter.add_representer(VersionedDict, vdict_representer)
print(yaml.round_trip_dump(y))
will give you:
!v2
bar: haha
foo: 3
baz:
- 1
- 2
- 3
roundtrip_dump
is a safe_dump
Please note that when you load this using yaml.load()
in some way, that your loader expects to find a constructor
for the !v2
tag type, unless you read the first line outside of the actual loading routine.
The above was done with ruamel.yaml
(of which I am the author) an enhanced version of PyYAML if you have to stick with PyYAML (e.g if you have to stick with YAML 1.1) then you should be able to make the necessary changes relatively easily. Just make sure you add the representer to the representer you are using to dump: SafeRepresenter
when using safe_dump
.
Upvotes: 1