In principle, this is possible because you can use such "start of file" comments in both directions, but this is not very well supported in the current ruamel.yaml 0.10 and, of course, not when starting from scratch (i.e. without changing existing file). Below is an easy and relatively good solution, but I would like to first introduce an ugly workaround and a step-by-step guide on how to do this.
Ugly
An ugly way to do this is to simply add a comment to the file before writing YAML data to it. That is, insert:
f.write('
just before ruamel.yaml.dump(...)
Step by step :
To insert a comment into the data structure so that the hack described above is not necessary, you first need to make sure that your d data is of type CommentedMap . If you compare the difference of this variable d with the one that has the comment by loading the commented out YAML back into c
import ruamel.yaml from ruamel.yaml.comments import Comment, CommentedSeq, CommentedMap d = CommentedMap()
This prints:
Comment(comment=[None, [CommentToken(value=u'# Data for Class A\n')]], items={}) Comment(comment=None, items={})
Comment has an attribute attribute comment that must be set in a list of 2 elements, which consists of an EOL comment (always only one) and a list of comments on the previous line (in the CommentTokens form)
To create a CommentToken, you need a (fake) StartMark that tells which column it starts with:
from ruamel.yaml.error import StreamMark start_mark = StreamMark(None, None, None, 0, None, None)
Now you can create a token:
from ruamel.yaml.tokens import CommentToken ct = CommentToken('# ' + comment + '\n', start_mark, None)
Assign the token as the first element of the previous list in your CommentedMap:
d.ca.comment = [None, [ct]] print d.ca
gives you:
Comment(comment=[None, [CommentToken(value='# Data for Class A\n')]], items={})
And finally:
print ruamel.yaml.dump(d, Dumper=ruamel.yaml.RoundTripDumper)
gives:
# Data for Class A B1: A1: [test, test2] A3: [test, test2] A2: - test - test2 B2: A1: [test, test2] A3: [test, test2] A2: - test - test2 B3: A1: [test, test2] A3: [test, test2] A2: - test - test2
Of course, you do not need to create an object c , this is just for illustration.
What you should use : To make the whole exercise a little easier, you can just forget about the details and the patch in the following method for CommentedBase once:
from ruamel.yaml.comments import CommentedBase def set_start_comment(self, comment, indent=0): """overwrites any preceding comment lines on an object expects comment to be without '#' and possible have mutlple lines """ from ruamel.yaml.error import StreamMark from ruamel.yaml.tokens import CommentToken if self.ca.comment is None: pre_comments = [] self.ca.comment = [None, pre_comments] else: pre_comments = self.ca.comments[1] if comment[-1] == '\n': comment = comment[:-1]
and then just do:
d.set_start_comment('Data for Class A')