ruyaml
ruyaml copied to clipboard
AttributeError trying to modify comment with yaml_set_start_comment
Using version ruyaml==0.19.2 (issue also occurred with master).
Generate a test file:
Python 3.7.2 (default, Mar 5 2019, 06:22:51)
[GCC 6.3.0 20170516] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from ruamel.yaml import YAML
>>> data = {'items': [{'one': 1, 'uno': '1'}, {'two': 2, 'duo': '2'}, {'three': 3}]}
>>> yaml = YAML(typ='rt')
>>> yaml.dump(data, stream=open('input.yaml', 'w'))
>>> print(open('input.yaml', 'r').read())
items:
- one: 1
uno: '1'
- two: 2
duo: '2'
- three: 3
Read the file and add a comment, this works as expected:
>>> yaml = YAML(typ='rt')
>>> data = yaml.load(open('input.yaml', 'r'))
>>> data['items'][0].yaml_set_start_comment('item 1')
>>> data['items'][1].yaml_set_start_comment('item 2')
>>> data['items'][2].yaml_set_start_comment('item 3')
>>> yaml = YAML(typ='rt')
>>> yaml.dump(data, stream=open('output.yaml', 'w'))
>>> print(open('output.yaml', 'r').read())
items:
# item 1
- one: 1
uno: '1'
# item 2
- two: 2
duo: '2'
# item 3
- three: 3
But if I read that file back in and try to change the comments, there is an error:
>>> yaml = YAML(typ='rt')
>>> data = yaml.load(open('output.yaml', 'r'))
>>> data['items'][0].yaml_set_start_comment('uno')
>>> data['items'][1].yaml_set_start_comment('duo')
>>> data['items'][2].yaml_set_start_comment('tre')
>>> yaml = YAML(typ='rt')
>>> yaml.dump(data, stream=open('output2.yaml', 'w'))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.7/site-packages/ruamel/yaml/main.py", line 451, in dump
return self.dump_all([data], stream, _kw, transform=transform)
File "/usr/local/lib/python3.7/site-packages/ruamel/yaml/main.py", line 465, in dump_all
self._context_manager.dump(data)
File "/usr/local/lib/python3.7/site-packages/ruamel/yaml/main.py", line 817, in dump
self._yaml.representer.represent(data)
File "/usr/local/lib/python3.7/site-packages/ruamel/yaml/representer.py", line 85, in represent
node = self.represent_data(data)
File "/usr/local/lib/python3.7/site-packages/ruamel/yaml/representer.py", line 112, in represent_data
node = self.yaml_representers[data_types[0]](self, data)
File "/usr/local/lib/python3.7/site-packages/ruamel/yaml/representer.py", line 1173, in represent_dict
return self.represent_mapping(tag, data)
File "/usr/local/lib/python3.7/site-packages/ruamel/yaml/representer.py", line 1018, in represent_mapping
node_value = self.represent_data(item_value)
File "/usr/local/lib/python3.7/site-packages/ruamel/yaml/representer.py", line 112, in represent_data
node = self.yaml_representers[data_types[0]](self, data)
File "/usr/local/lib/python3.7/site-packages/ruamel/yaml/representer.py", line 1188, in represent_list
return self.represent_sequence(tag, data)
File "/usr/local/lib/python3.7/site-packages/ruamel/yaml/representer.py", line 935, in represent_sequence
self.merge_comments(node_item, item_comments.get(idx))
File "/usr/local/lib/python3.7/site-packages/ruamel/yaml/representer.py", line 957, in merge_comments
assert val is None or val == nc
File "/usr/local/lib/python3.7/site-packages/ruamel/yaml/tokens.py", line 276, in __eq__
if self.start_mark != other.start_mark:
File "/usr/local/lib/python3.7/site-packages/ruamel/yaml/error.py", line 52, in __ne__
return not self.__eq__(other)
File "/usr/local/lib/python3.7/site-packages/ruamel/yaml/error.py", line 44, in __eq__
if self.line != other.line or self.column != other.column:
AttributeError: 'CommentMark' object has no attribute 'line'
PR welcomed! :D
I've converted the above into a (failing) test in PR #35, but haven't managed to fix it.
It seemed from my experimentation that the assert in representer.py:957 is the problem, and removing it allows the comments to be saved, but I can't figure out how to clear the comments, so they just keep adding on to the previous comments every time the file is round tripped, which is undesirable.