How do you remove a comment in ruamel.yaml?
Asked Answered
B

2

8

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.
Badillo answered 21/8, 2019 at 19:47 Comment(0)
D
5

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)
Demb answered 21/8, 2019 at 20:43 Comment(0)
E
0

Sorry for piggy-backing on Anthon's answer, but I'd really highlight the "hidden" logic from his code which actually allows to remove the comment easily in one line without dirty-injecting anything into the module:

object.ca.items.pop(key, None)

Where key is the actual key you want to clean comment for. That's it!

Eurydice answered 15/2, 2021 at 15:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.