From da9b03d1c4a94c0f2bd2e5b6edab2cfcaee0c3a6 Mon Sep 17 00:00:00 2001 From: Dipak Date: Sat, 8 Aug 2026 14:42:49 +0530 Subject: [PATCH] Start a new line before the closing bracket of a commented array Array.as_string() renders a non-multiline array by concatenating its raw items and appending "]". When add_line() was given a comment, the comment was the last item, so the bracket landed inside it: >>> a = tomlkit.array() >>> a.add_line("foo", comment="bar") >>> a.as_string() '[\n "foo", # bar]' The result no longer parses. Emit a newline (and the array's indent) before the bracket when the last rendered item is a comment. Fixes #580 --- tests/test_items.py | 29 +++++++++++++++++++++++++++++ tomlkit/items.py | 8 +++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/tests/test_items.py b/tests/test_items.py index e331cae..85defec 100644 --- a/tests/test_items.py +++ b/tests/test_items.py @@ -529,6 +529,35 @@ def test_array_add_line() -> None: ) +def test_array_add_line_trailing_comment_does_not_hide_bracket() -> None: + t = api.array() + t.add_line("foo", comment="bar") + + assert ( + t.as_string() + == """[ + "foo", # bar +]""" + ) + + doc = api.document() + doc.add("array", t) + assert parse(doc.as_string())["array"] == ["foo"] + + +def test_array_add_line_trailing_comment_closing_line_is_not_doubled() -> None: + t = api.array() + t.add_line("foo", comment="bar") + t.add_line(indent="") + + assert ( + t.as_string() + == """[ + "foo", # bar +]""" + ) + + def test_array_add_line_multiline_comment_is_rejected() -> None: t = api.array() with pytest.raises(ValueError, match="line breaks"): diff --git a/tomlkit/items.py b/tomlkit/items.py index 31369b0..6c87399 100644 --- a/tomlkit/items.py +++ b/tomlkit/items.py @@ -1464,7 +1464,13 @@ def multiline(self, multiline: bool) -> Array: def as_string(self) -> str: if not self._multiline or not self._value: - return f"[{''.join(v.as_string() for v in self._iter_items())}]" + items = list(self._iter_items()) + body = "".join(v.as_string() for v in items) + if items and isinstance(items[-1], Comment): + # A comment runs to the end of the line, so the closing bracket + # has to start a new one or it would be commented out. + body += "\n" + self.trivia.indent + return f"[{body}]" s = "[\n" s += "".join(