From 622d5164f924b9d72a8bb9832a7594ecb3a38289 Mon Sep 17 00:00:00 2001 From: pasmud Date: Thu, 12 Nov 2026 23:41:30 +1100 Subject: [PATCH] Reject non-table array-of-tables assignments before mutation --- tests/test_items.py | 18 ++++++++++++++++++ tomlkit/items.py | 7 +++++++ 2 files changed, 25 insertions(+) diff --git a/tests/test_items.py b/tests/test_items.py index 13853fb2..1b5e1de0 100644 --- a/tests/test_items.py +++ b/tests/test_items.py @@ -240,6 +240,24 @@ def test_aot_integer_assignment_updates_list_storage() -> None: assert parse(doc.as_string()).unwrap() == doc.unwrap() +@pytest.mark.parametrize( + "index", [0, -1, slice(None), slice(None, None, 2), slice(None, None, -2)] +) +@pytest.mark.parametrize("invalid", [42, "text", [1, 2], api.inline_table()]) +def test_aot_assignment_rejects_non_tables_without_mutation( + index: int | slice, invalid: Any +) -> None: + source = "[[a]]\nx = 1\n[[a]]\nx = 2\n[[a]]\nx = 3\n" + doc = parse(source) + replacement = [{"x": 3}, invalid] if isinstance(index, slice) else invalid + with pytest.raises(ValueError, match="Unsupported assignment value type"): + doc["a"][index] = replacement + assert doc.as_string() == source + assert doc["a"] == [{"x": 1}, {"x": 2}, {"x": 3}] + assert doc.unwrap() == {"a": [{"x": 1}, {"x": 2}, {"x": 3}]} + assert json.loads(json.dumps(doc)) == doc.unwrap() + + def test_aot_delete_after_slice_insertion() -> None: doc = parse("[[a]]\nx = 1\n") doc["a"][1:1] = [{"x": 2}] diff --git a/tomlkit/items.py b/tomlkit/items.py index 4d56f564..6e334ac7 100644 --- a/tomlkit/items.py +++ b/tomlkit/items.py @@ -2445,8 +2445,15 @@ def __getitem__(self, key: int | slice) -> Table | list[Table]: def __setitem__(self, key: slice | int, value: Any) -> None: # type: ignore[override] if isinstance(key, slice): value = [item(v, _parent=self) for v in value] + for table in value: + if not isinstance(table, Table): + raise ValueError( + f"Unsupported assignment value type: {type(table)}" + ) else: value = item(value, _parent=self) + if not isinstance(value, Table): + raise ValueError(f"Unsupported assignment value type: {type(value)}") self._body[key] = value list.__setitem__(self, key, value)