Skip to content

Fix single-line Array losing its closing bracket after a trailing comment - #602

Open
afonsojanu wants to merge 1 commit into
python-poetry:masterfrom
afonsojanu:fix-array-trailing-comment-closing-bracket
Open

afonsojanu wants to merge 1 commit into
python-poetry:masterfrom
afonsojanu:fix-array-trailing-comment-closing-bracket

Conversation

@afonsojanu

Copy link
Copy Markdown

Summary

Array.as_string() for a non-multiline array renders by concatenating the raw text of each item, including any comment attached through add_line(). Since a # comment runs to the end of its physical line, if that comment happens to be the last thing rendered before the closing ], the bracket gets swallowed into the comment text and the array stops being valid TOML:

>>> import tomlkit
>>> a = tomlkit.array()
>>> a.add_line("foo", comment="bar")
>>> a.as_string()
'[\n    "foo", # bar]'
>>> doc = tomlkit.document()
>>> doc.add("array", a)
>>> tomlkit.loads(doc.as_string())
tomlkit.exceptions.UnexpectedCharError: Unexpected character: '\x00' at line 2 col 0

This matches #580: the existing workaround is to always finish with a manual add_line(indent="") call to supply the missing newline yourself, which is easy to forget and produces a document that silently fails to round-trip.

Fix

In the non-multiline branch of Array.as_string(), if the rendered content ends with a comment and isn't already terminated by a newline, a newline (plus the array's indent) is appended before the closing bracket. This only changes output for the specific case that was broken; arrays without a trailing comment, and the already-documented workaround, render exactly as before.

Testing

Added test_array_add_line_with_comment_on_last_line_round_trips in tests/test_items.py, which reproduces the issue and asserts the array parses back correctly. Ran the full suite (pytest tests/ --ignore=tests/test_toml_tests.py, the ignored module needs a submodule I didn't have checked out) plus ruff check / ruff format --check on the touched files; everything passes.

Fixes #580.

Agent Drafting Metadata

  • Agent: Claude Code
  • Model: Claude (Sonnet 5)
  • Notes: I used Claude Code to investigate the issue, write the fix in tomlkit/items.py, and add the regression test. I reviewed the diff, ran the test suite and linters myself, and wrote this description.

…ment

Array.as_string() for a non-multiline array just concatenates the raw
text of each item, including any comment added through add_line(). A
"#" comment runs to the end of its physical line, so when the comment
happens to be the last thing rendered before "]", the bracket gets
swallowed into the comment and the array no longer parses.

    >>> a = tomlkit.array()
    >>> a.add_line("foo", comment="bar")
    >>> a.as_string()
    '[\n    "foo", # bar]'   # note: no closing bracket outside the comment

Force a newline before the bracket whenever the rendered content would
otherwise end with an unterminated comment, so the array keeps
round-tripping through tomlkit.loads().

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Array.add_line() doesn't serialize as documented (or expected) and can even produce syntactically invalid TOML

1 participant