From c6f8165a503b84853dc3ba6c768b4e645323a83b Mon Sep 17 00:00:00 2001 From: hakarrr Date: Sat, 24 Oct 2026 14:06:17 +0530 Subject: [PATCH 1/2] Preserve line boundaries between array-of-tables elements --- tomlkit/container.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tomlkit/container.py b/tomlkit/container.py index 9265c740..a7c91521 100644 --- a/tomlkit/container.py +++ b/tomlkit/container.py @@ -819,6 +819,12 @@ def _render_aot(self, key: Key, aot: AoT, prefix: str | None = None) -> str: cur = "" _key = decode(_key) for table in aot.body: + if ( + cur + and not cur.rstrip(" ").endswith("\n") + and "\n" not in table.trivia.indent + ): + cur += "\n" cur += self._render_aot_table(table, prefix=_key) return cur From 7ad04dafec5a6eba527a3fe78f8354f25cfb9123 Mon Sep 17 00:00:00 2001 From: hakarrr Date: Sat, 24 Oct 2026 14:07:03 +0530 Subject: [PATCH 2/2] Test moving unterminated array-of-tables elements Add tests for AOT insert functionality and table spacing preservation. --- tests/test_items.py | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/tests/test_items.py b/tests/test_items.py index 27a1c6e2..40c1e505 100644 --- a/tests/test_items.py +++ b/tests/test_items.py @@ -1683,3 +1683,34 @@ def test_out_of_order_table_proxy_membership() -> None: _ = 123 in table # membership must not resolve values or mutate the document assert doc.as_string() == content + + +@pytest.mark.parametrize( + "ending", ["x=1", "x=1# one", "# empty", "", "x=1\n[a.child]\ny=3# child"] +) +@pytest.mark.parametrize("newline", ["\n", "\r\n"]) +def test_aot_insert_preserves_unterminated_table_boundaries( + ending: str, newline: str +) -> None: + doc = parse(("[[a]]\nx=2\n[[a]]\n" + ending).replace("\n", newline)) + aot = doc["a"] + moved = aot.pop() + aot.insert(0, moved) + expected = [moved.unwrap(), {"x": 2}] + rendered = api.dumps(doc) + assert parse(rendered)["a"].unwrap() == expected + assert aot.unwrap() == expected + assert aot == expected + if "#" in ending: + assert ending.split("#")[-1] in rendered + assert aot[0] is moved + assert api.dumps(doc) == rendered + + +def test_aot_insert_keeps_existing_table_spacing() -> None: + text = "[[a]]\nx=2\n\n[[a]] # one\nx=1\n" + doc = parse(text) + aot = doc["a"] + moved = aot.pop() + aot.insert(0, moved) + assert api.dumps(doc) == "[[a]] # one\nx=1\n[[a]]\nx=2\n\n"