fruits = CommentedSeq()
fruits.append('banana')
fruits.yaml_set_comment_before_after_key(0, 'comments above', after='comments below')
yaml.dump({'fruits': fruits}, sys.stdout)
I'd like the output to be the following:
fruits:
# comments above
- banana
# comments below
But from my test, comments below
is discarded.
The (undocumented) method you use is called yaml_set_comment_before_or_after_key
. That
last part key
refers to the key of key-value pair in a mapping. You are using a sequence
and although there is some similarity of handling both on round-trip, they are not handled in the same way.
First thing to do in this case is see if your desired results round-trips at all:
import sys
import ruamel.yaml
yaml_str = """\
fruits:
# comments above
- banana
# comments below
"""
yaml = ruamel.yaml.YAML()
yaml.indent(sequence=4, offset=2)
data = yaml.load(yaml_str)
yaml.dump(data, sys.stdout)
This gives:
fruits:
# comments above
- banana
# comments below
so it does round-trip.
Then compare the comments attached to the loaded data with your constructed data:
from ruamel.yaml.comments import CommentedSeq
fruits = CommentedSeq()
fruits.append('banana')
fruits.yaml_set_comment_before_after_key(0, 'comments above', after='comments below')
print('loaded: ', data['fruits'].ca)
print('generated:', fruits.ca)
that is not the same:
loaded: Comment(comment=[None, [CommentToken('# comments above\n', line: 1, col: 2)]],
items={0: [CommentToken('\n # comments below\n', line: 3, col: 2), None, None, None]})
generated: Comment(comment=None,
items={0: [None, [CommentToken('# comments above\n', col: 0)], None, [CommentToken('# comments below\n', col: 2)]]})
The loaded data doesn't have comments above
associated with sequence element 0. It is a comment
that exists before the sequence start. You can still get what you want:
from ruamel.yaml.tokens import CommentToken
from ruamel.yaml.error import CommentMark
indent = 2
fruits.ca.comment = [None, [CommentToken('# comments above\n', CommentMark(indent))]]
fruits.ca.items[0] = [CommentToken(f'\n{" "*indent}# comments below\n', CommentMark(0)), None, None, None]
yaml.dump({'fruits': fruits}, sys.stdout)
which gives:
fruits:
# comments above
- banana
# comments below
Make sure you pin the ruamel.yaml version for your application, when you are using these kind of internals that will change.