TypeError: 'CommentToken' object is not iterable
ruamel.yaml is a YAML 1.2 parser/emitter for Python
Brought to you by:
anthon
Here is a minimal working example that reproduces the issue:
"""
ruamel.yaml bug: yaml_value_comment_extend() crashes when adding EOL comment
to a key that already has a comment (loaded from YAML)
Bug location: ruamel/yaml/comments.py, method yaml_value_comment_extend()
When loading YAML with existing EOL comments, then calling yaml_add_eol_comment()
on the same key, the else branch in yaml_value_comment_extend() executes:
r[3].extend(comment[0])
But comment[0] is a CommentToken, not a list, causing:
TypeError: 'CommentToken' object is not iterable
"""
from ruamel.yaml import YAML, version_info
from io import StringIO
print(f"ruamel.yaml version: {'.'.join(map(str, version_info))}")
yaml = YAML()
def test_add_eol_comment_to_existing_comment():
"""
Minimal reproduction:
1. Load YAML that has an existing EOL comment on a key with list value
2. Try to add/update the EOL comment on that same key
3. Crash with TypeError: 'CommentToken' object is not iterable
"""
# YAML with existing EOL comment on 'items' key
yaml_content = """\
config:
items: # existing comment
- name: item1
value: 100
"""
data = yaml.load(yaml_content)
# Debug: show the internal comment structure after loading
print("After loading, ca.items['items']:")
print(f" {data['config'].ca.items['items']}")
# Output: [None, None, CommentToken('# existing comment\n', ...), []]
# Note: r[3] is an empty list []
# This crashes when trying to add EOL comment to a key that already has one
# The bug is in yaml_value_comment_extend() else branch:
# - r = [None, None, CommentToken(...), []] (from loaded YAML)
# - comment = [CommentToken(...), None] (new comment)
# - r[3].extend(comment[0]) <-- BUG: comment[0] is CommentToken, not list!
data['config'].yaml_add_eol_comment('new comment', key='items')
# Expected: comment should be updated to 'new comment'
stream = StringIO()
yaml.dump(data, stream)
print(stream.getvalue())
def workaround():
"""
Workaround: delete existing comment before adding new one
"""
yaml_content = """\
config:
items: # existing comment
- name: item1
value: 100
"""
data = yaml.load(yaml_content)
# Workaround: clear existing comment first
if 'items' in data['config'].ca.items:
del data['config'].ca.items['items']
# Now this works
data['config'].yaml_add_eol_comment('new comment', key='items')
stream = StringIO()
yaml.dump(data, stream)
print("Workaround output:")
print(stream.getvalue())
if __name__ == '__main__':
print("=" * 60)
print("Bug reproduction:")
print("=" * 60)
try:
test_add_eol_comment_to_existing_comment()
except TypeError as e:
print(f"\nCrashed with: {type(e).__name__}: {e}")
print("\n" + "=" * 60)
print("Workaround:")
print("=" * 60)
workaround()
output:
(chatui) PS E:\program\ChatUI\tmp_test> uv run .\ruamel_yaml_bug_report.py
ruamel.yaml version: 0.19.1
============================================================
Bug reproduction:
============================================================
After loading, ca.items['items']:
[None, None, CommentToken('# existing comment\n', line: 1, col: 11), []]
Crashed with: TypeError: 'CommentToken' object is not iterable
============================================================
Workaround:
============================================================
Workaround output:
config:
items: # new comment
- name: item1
value: 100