From 31c0531153a9bb3ae1456383949bf70fc26e5020 Mon Sep 17 00:00:00 2001 From: KennyMcSimpson <70093673+KennyMcSimpson@users.noreply.github.com> Date: Sat, 24 Oct 2026 21:08:47 +0800 Subject: [PATCH 1/2] Fix appends after standalone array comments --- CHANGELOG.md | 4 ++++ tests/test_items.py | 22 ++++++++++++++++++++++ tomlkit/items.py | 10 +++++++--- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f414f212..61649145 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Fixed + +- Add a missing separator when appending to an array whose last value is followed by standalone comments. + ## [0.15.2] - 2026-10-16 ### Changed diff --git a/tests/test_items.py b/tests/test_items.py index 27a1c6e2..e8d9725d 100644 --- a/tests/test_items.py +++ b/tests/test_items.py @@ -521,6 +521,28 @@ def test_modify_array_with_comment() -> None: assert doc.as_string() == "x = [\n 2\n]" +@pytest.mark.parametrize("trailing_comma", [False, True]) +@pytest.mark.parametrize("operation", ["append", "extend", "insert"]) +@pytest.mark.parametrize("comments", ["# trailing\n", "# first\n# trailing\n"]) +def test_append_after_standalone_array_comments( + trailing_comma: bool, operation: str, comments: str +) -> None: + doc = parse("x = [\n1" + ("," if trailing_comma else "") + "\n" + comments + "]\n") + array = doc["x"] + if operation == "append": + array.append(2) + elif operation == "extend": + array.extend([2, 3]) + else: + array.insert(len(array) + 5, 2) + + expected = [1, 2, 3] if operation == "extend" else [1, 2] + rendered = doc.as_string() + assert array == expected + assert parse(rendered)["x"] == expected + assert comments in rendered + + def test_append_to_multiline_array_with_comment() -> None: doc = parse( """\ diff --git a/tomlkit/items.py b/tomlkit/items.py index 30d8a4f2..db8c93f5 100644 --- a/tomlkit/items.py +++ b/tomlkit/items.py @@ -1675,6 +1675,10 @@ def insert(self, pos: int, value: Any) -> None: # type: ignore[override] indent = self._value[idx].indent if idx > 0: last_item = self._value[idx - 1] + last_value_item = last_item + if pos > 0 and length: + # Standalone comments may follow the preceding array value. + last_value_item = self._value[self._index_map[min(pos, length) - 1]] if indent is None: indent = last_item.indent if not isinstance(last_item.value, Null) and "\n" in default_indent: @@ -1683,14 +1687,14 @@ def insert(self, pos: int, value: Any) -> None: # type: ignore[override] comma = last_item.comma comma_in_indent = indent is not None and "," in indent.s if ( - last_item.comma is None - and not isinstance(last_item.value, Null) + last_value_item.comma is None + and not isinstance(last_value_item.value, Null) and not comma_in_indent ): # Add comma to the last item to separate it from the following # items, unless the new item's indent already starts with a # comma (comma-first style). - last_item.comma = Whitespace(",") + last_value_item.comma = Whitespace(",") if indent is not None and "," in indent.s: # Comma-first style: the item that will follow the new one brings # its own leading comma, so the new item must not add a trailing From e44acf622658113928f3a243dce47d666c89ac72 Mon Sep 17 00:00:00 2001 From: KennyMcSimpson <70093673+KennyMcSimpson@users.noreply.github.com> Date: Sun, 25 Oct 2026 02:25:15 +0800 Subject: [PATCH 2/2] Keep the Python 3.9 Linux job on Ubuntu 24.04 --- .github/workflows/tests.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 351c79e7..b8990173 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -18,6 +18,13 @@ jobs: matrix: os: [ubuntu-latest, macos-latest, windows-latest] python-version: [3.9, "3.10", 3.11, 3.12, 3.13, 3.14] + exclude: + - os: ubuntu-latest + python-version: 3.9 + include: + # setup-python has no Python 3.9 build for Ubuntu 26.04. + - os: ubuntu-24.04 + python-version: 3.9 steps: - uses: actions/checkout@v6