I am writing a YAML file using https://pypi.python.org/pypi/ruamel.yaml
The code is like this:
import ruamel.yaml
from ruamel.yaml.comments import CommentedSeq
d = {}
for m in ['B1', 'B2', 'B3']:
d2 = {}
for f in ['A1', 'A2', 'A3']:
d2[f] = CommentedSeq(['test', 'test2'])
if f != 'A2':
d2[f].fa.set_flow_style()
d[m] = d2
with open('test.yml', "w") as f:
ruamel.yaml.dump(
d, f, Dumper=ruamel.yaml.RoundTripDumper,
default_flow_style=False, width=50, indent=8)
I just want to add comment at the top like:
# Data for Class A
Before the YAML data.
That is possible in principle, because you can round-trip such "start-of-file" comments, but it is not nicely supported in the current ruamel.yaml 0.10 and certainly not when "starting from scratch" (i.e. no changing an existing file). At the bottom is an easy an relatively nice solution but I would first like to present an ugly workaround and a step-wise how to get this done.
Ugly:
The ugly way to do this is to just add the comment to the file before you write the YAML data to it. That is insert:
just before
ruamel.yaml.dump(...)
Step by step:
To insert the comment on the data structure, so the above hack is not necessary, you first need to make sure your
d
data is aCommentedMap
type. If you compare the difference of thatd
variable with one that has a the comment by loading the commented YAML back intoc
This prints:
A
Comment
has an attributecomment
that needs to be set to a 2 element list that consist of the EOL comment (always only one) and a list of preceding line comments (in the form ofCommentTokens
)To create a CommentToken you need a (fake) StartMark that tells which column it starts:
Now you can create the token:
Assign the token as the first element of the preceding list on your CommentedMap:
gives you:
And finally:
gives:
Of course you don't need to create the
c
object, that is just for illustration.What you should use: To make the whole exercise somewhat easier you can just forget about the details and patch in the following method to
CommentedBase
once:and then just do:
Within your
with
block, you can write anything you want to the file. Since you just need a comment at the top, add a call tof.write()
before you call ruamel: