ruyaml icon indicating copy to clipboard operation
ruyaml copied to clipboard

AttributeError trying to modify comment with yaml_set_start_comment

Open tompaton opened this issue 5 years ago • 2 comments

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'

tompaton avatar Dec 16 '20 11:12 tompaton

PR welcomed! :D

ssbarnea avatar Dec 17 '20 16:12 ssbarnea

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.

tompaton avatar Jan 02 '21 10:01 tompaton