简体   繁体   中英

How to avoid an error when applying comments eol and before a key to yaml using ruamel.yaml?

I'm constructing a yaml file from data and adding comments to sections that need manual user editing. For each category of data, I'm including a top level comment, but I also want to include end of line (eol) comments on the list items. I'm encountering an error internal to ruamel code when attempting this.

I'm using ruamel.yaml 0.15.96. This is the error:

AttributeError: 'NoneType' object has no attribute 'append'

It occurs in comments.py , line 261, in yaml_set_comment_before_after_key .

I think because I'm setting an eol comment, the data structure is different, so when I add a before comment, this line executes: c[1].append(comment_token(com, start_mark)) and fails because c[1] is None instead of [] .

# Pseudocode, removed irrelevant details
data = CommentedMap(TopLevelData)
data.yaml_set_start_comment(TOP_LEVEL_COMMENT)
temp_list = CommentedSeq()

for top_comment, start_index, matches in match_categories:
    components = self._matches_to_components(matches)
    for idx, subcomponent in enumerate(components):
         temp_list.append(data)
         temp_list.yaml_add_eol_comment(comment=inline_comment,
                                        key=idx)
    temp_list.yaml_set_comment_before_after_key(key=start_index,
                                                before=top_comment,
                                                indent=OFFSET)
data['subcomponents'] = temp_list

I expect the output to look something like this:

# TOP_LEVEL_COMMENT
name: hydrated-cluster
subcomponents:
  # top_comment
  - data: elasticsearch-fluentd-kibana # inline comment

Your pseudo-code hides what you are doing wrong. If you would take the time to make a minimal non-working example, that generates that error, you'll notice that it will just work. From that you can work back to determine where in your code the error lies.

Working with the same classes and methods that you used:

import sys
import ruamel.yaml
from ruamel.yaml.comments import CommentedMap, CommentedSeq

data = CommentedMap(dict(name="hydrated-cluster"))
data.yaml_set_start_comment("TOP_LEVEL_COMMENT")
temp_list = CommentedSeq()

d2 = CommentedMap(data="elasticsearch-fluentd-kibana")
d2.yaml_add_eol_comment(comment="# inline comment", key='data')
data['subcomponents'] = l3 = CommentedSeq([d2])
l3.yaml_set_comment_before_after_key(key=0, before="top comment", indent=2)

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

and the above gives what you expect:

# TOP_LEVEL_COMMENT
name: hydrated-cluster
subcomponents:
  # top comment
  - data: elasticsearch-fluentd-kibana  # inline comment

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM