From 75de0cbce27330a8e2fbdcfd23a8bf5f25b842b5 Mon Sep 17 00:00:00 2001 From: fei <204683769+feiiiiii5@users.noreply.github.com> Date: Sun, 25 Oct 2026 11:17:12 +0800 Subject: [PATCH] Carry _table_keys through Container.__copy__ The copy dropped the table-key bookkeeping that __setstate__ preserves on pickle, so the merge heuristic in _handle_merge crashed with IndexError when appending a table whose name already existed in the copy. --- CHANGELOG.md | 4 ++++ tests/test_toml_document.py | 16 ++++++++++++++++ tomlkit/container.py | 1 + 3 files changed, 21 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f414f212..a6608988 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Fixed + +- `Container.__copy__` now carries over `_table_keys`, so appending a table to a copied container no longer raises `IndexError` when a table with the same name already exists. + ## [0.15.2] - 2026-10-16 ### Changed diff --git a/tests/test_toml_document.py b/tests/test_toml_document.py index 84b114b9..f5f3204a 100644 --- a/tests/test_toml_document.py +++ b/tests/test_toml_document.py @@ -486,6 +486,22 @@ def test_toml_document_can_be_copied() -> None: assert json.loads(json.dumps(doc)) == {"foo": {"bar": 1}} +def test_toml_document_copy_keeps_table_keys() -> None: + doc = parse("[a.b]\nx = 1\n") + + doc_copy = doc.copy() + doc_copy.append("a", tomlkit.table(True).append("d", 3)) + + # The copy accepts the append instead of raising IndexError, and the + # merged rendering stays parseable with both tables intact. (The copy is + # shallow, so table objects are shared with the original — only the + # container's own key bookkeeping is what __copy__ must duplicate.) + reloaded = parse(doc_copy.as_string()) + assert reloaded["a"]["b"]["x"] == 1 + assert reloaded["a"]["d"] == 3 + assert doc._table_keys == ["a"] + + def test_getting_inline_table_is_still_an_inline_table() -> None: content = """\ [tool.poetry] diff --git a/tomlkit/container.py b/tomlkit/container.py index 9265c740..63b9289e 100644 --- a/tomlkit/container.py +++ b/tomlkit/container.py @@ -1103,6 +1103,7 @@ def __copy__(self) -> Self: c._body += self.body c._map.update(self._map) c._out_of_order_keys |= self._out_of_order_keys + c._table_keys += self._table_keys return c