On Python 2.7, and on Python 3.X with at least ruamel.yaml 0.11.11, this works fine:
import ruamel.yaml
yaml_str = """\
first_name: Art
occupation: Architect # This is an occupation comment
about: Art Vandelay is a fictional character that George invents...
"""
data = ruamel.yaml.round_trip_load(yaml_str)
data.insert(1, 'last name', 'Vandelay')
print(ruamel.yaml.round_trip_dump(data))
gives:
first_name: Art
last name: Vandelay
occupation: Architect # This is an occupation comment
about: Art Vandelay is a fictional character that George invents...
as the end-of-line comments are associated with the key of the line in the CommentedMap. (Python 2.7.11 on Linux Mint with ruamel.yaml 0.11.10.)
This will not work on older versions of ruamel.yaml with Python3 as the .insert() you are using is a feature of the full-fledged ruamel.ordereddict and the OrderedDict in the standard library doesn't have that method. Therefore you need to graft an .insert() function onto the CommentedMap:
import ruamel.yaml
from ruamel.yaml.comments import CommentedMap
from ruamel.yaml.compat import ordereddict
yaml_str = """\
first_name: Art
occupation: Architect # This is an occupation comment
about: Art Vandelay is a fictional character that George invents...
"""
def com_insert(self, pos, key, value, comment=None):
od = ordereddict()
od.update(self)
for k in od:
del self[k]
for index, old_key in enumerate(od):
if pos == index:
self[key] = value
self[old_key] = od[old_key]
if comment is not None:
self.yaml_add_eol_comment(comment, key=key)
CommentedMap.insert = com_insert
data = ruamel.yaml.round_trip_load(yaml_str)
data.insert(1, 'last name', 'Vandelay', comment="new key")
print(ruamel.yaml.round_trip_dump(data))
gives on Python3:
first_name: Art
last name: Vandelay # new key
occupation: Architect # This is an occupation comment
about: Art Vandelay is a fictional character that George invents...
Please note that there is an optional parameter for insert() that allows you to specify a comment for the newly inserted key-value pair. The above works because deleting a key from a CommentedMap doesn't remove the comment associated with the key. So I temporarily park the old key-value pairs in od
delete all key-values, and then copy them back inserting the new stuff at the right moment
The above insert, with comment, has been added in ruamel.yaml 0.11.11 for
both Python 2 and 3
The .round_trip_load() is equivalent to .load(...., Loader=ruamel.yaml.RoundTripLoader, ...) and .round_trip_dump() to `.dump(....., Dumper=ruamel.yaml.RoundTripDumper, allow_unicode=True, ...)