Как я могу добавить комментарий с помощью ruamel.yaml

Я пытаюсь создать структуру данных с помощью ruamel.yaml и хочу добавить комментарии перед сбросом и/или повторной загрузкой. К сожалению, все примеры сначала загружают какую-то строку с дампером туда и обратно или используют уже не существующие API.

Вот что я пытаюсь сбросить:

test: asdf # Test Comment!

Я пробовал следующее:

insert = ruamel.yaml.comments.CommentedMap()
start_mark = ruamel.yaml.error.CommentMark(0)
insert['test'] = 'asdf'
insert.ca.items['test'] = [ None,
    [ruamel.yaml.CommentToken(value='# Test Comment!', start_mark=start_mark, end_mark=None)],
    None,
    None
]
ruamel.yaml.round_trip_dump(insert, sys.stdout)

который печатает.

# Test Comment!test: asdf

Каким-то образом комментарий находится впереди, а не позади значений. Что я делаю не так?


person spaceman_spiff    schedule 16.05.2019    source источник


Ответы (2)


Вы можете попытаться сделать это, добавив CommentTokens, но тип start_mark должен исходить из ruamel.yaml.error.

Гораздо проще сделать insert CommentedMap (именно так будет загружено сопоставление при выполнении обычной загрузки туда и обратно), а затем использовать его метод yaml_add_eol_comment:

import sys
import ruamel.yaml


insert = ruamel.yaml.comments.CommentedMap()
insert['test'] = 'asdf'
insert.yaml_add_eol_comment('Test Comment!', 'test', column=0)

yaml = ruamel.yaml.YAML()
# yaml.indent(mapping=4, sequence=4, offset=2)
yaml.dump(insert, sys.stdout)

который дает:

test: asdf # Test Comment!

column=0 является необязательным. Если вы не укажете начальный столбец, вы получите два пробела перед тем, как #, 0 попытается протолкнуть его полностью вперед, но, конечно, пара ключ-значение мешает.

Вы можете указать # в комментарии EOL, который вы указываете для метода yaml_add_eol_comment, но если его там нет, он будет добавлен.

Если у вас есть несколько комментариев после нескольких ключей в последовательных строках и вы хотите, чтобы ваши комментарии были выровнены, вам нужно указать только столбец первого добавленного.

person Anthon    schedule 16.05.2019
comment
Спасибо за ответ - это решает. Как-то я пропустил yaml_add_eol_comment метод CommentedMap - person spaceman_spiff; 16.05.2019
comment
Я не думаю, что это есть в документации, так бывает, когда разработчик библиотеки ленивый парень. - person Anthon; 16.05.2019

Что касается последних документов, https://yaml.readthedocs.io/en/latest/example.html

CommentedMap, который представляет собой конструкцию, подобную dict, которую получают при двусторонней загрузке, поддерживает вставку ключа в определенную позицию, при этом возможно добавление комментария:

import sys
from ruamel.yaml import YAML

yaml_str = """\
key: value # first line and comment!
"""

yaml = YAML()
data = yaml.load(yaml_str)
data.insert(1, 'test', 'asdf', comment="Test Comment!")
yaml.dump(data, sys.stdout)

Выход:

key: value # first line and comment!
test: asdf # Test Comment!
person Brock    schedule 16.05.2019
comment
Думаю, мне следует иногда читать документацию, а не просто писать ее. Предупреждение: хотя это работает, это не дает вам контроля над столбцом, в котором начинается комментарий. Если бы вы загрузили строку без комментариев, в вашем # Test Comment! было бы два пробела между asdf и # - person Anthon; 16.05.2019
comment
Спасибо за ответ, но я не могу загрузить строку yaml, потому что она еще не существует, поэтому это не решает мою проблему. - person spaceman_spiff; 16.05.2019