Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you remove a comment in ruamel.yaml?

I really like how ruamel.yaml can Round-trip comments, but I haven't figured out how to remove a comment from a YAML file.

#!/usr/bin/env python3
from ruamel.yaml import YAML
import sys

yaml = YAML()
yaml.preserve_quotes = True

with open(sys.argv[1], 'r') as f:
    object = yaml.load(f)
if sys.argv[2] == 'add':
    object['key'] = "value"
    object.yaml_add_eol_comment('Some comment', 'key')
if sys.argv[2] == 'remove':
    # This line does not work: This method does not exist.
    object.yaml_remove_eol_comment('key')


yaml.dump(object, open(sys.argv[1],'w'))

Other things I've tried

object.yaml_add_eol_comment('','key') # String index error.
object.yaml_add_eol_comment(' ', 'key') # This creates a comment like `#  `.
object.yaml_add_eol_comment(None, 'key') # Error when trying to subscript it.
v = object['key']; del object['key']; object['key'] = v # The comment still sticks around.
like image 725
earboxer Avatar asked Aug 21 '19 19:08

earboxer


1 Answers

There is no functionality in the form of method on loaded data to do that, but you can inspect the comments attached to a loaded collection (mapping or sequence) and that will look like:

Comment(comment=None,
  items={'key': [None, None, CommentToken('# Some comment\n', line: 1, col: 11), None]})

That is, it contains a dict which contains keys (of the original mapping) that have an associated comment. You have to delete that entry, as not doing so makes the comment reappear (when using the same key).

import sys
import ruamel.yaml

yaml_str = """\
a: 52
key: value # Some comment
"""

yaml = ruamel.yaml.YAML()
data = yaml.load(yaml_str)
# print(data.ca) # to see the comment attribute
del data.ca.items['key']
yaml.dump(data, sys.stdout)

which gives:

a: 52
key: value

If you want to delete all comments, you can also do

yaml.dump(dict(data), sys.stdout)

on the freshly loaded data.

This can be easily added as a method as well:

import sys
import ruamel.yaml

yaml_str = """\
a: 52
key: value # Some comment
"""

def my_yaml_remove_eol_comment(self, key):
    self.ca.items.pop(key, None)

ruamel.yaml.comments.CommentedMap.yaml_remove_eol_comment = my_yaml_remove_eol_comment


yaml = ruamel.yaml.YAML()

data = yaml.load(yaml_str)
data.yaml_remove_eol_comment('key')
yaml.dump(data, sys.stdout)
like image 159
Anthon Avatar answered Oct 17 '22 23:10

Anthon