diff --git a/tests/test_toml_document.py b/tests/test_toml_document.py index 84b114b9..18a12be2 100644 --- a/tests/test_toml_document.py +++ b/tests/test_toml_document.py @@ -689,6 +689,36 @@ def test_set_value_on_out_of_order_table_with_empty_concrete_part() -> None: assert parse(doc.as_string()).unwrap() == {"x": {"y": {"z": {"w": {}}}, "c": 3}} +@pytest.mark.parametrize("path", ["hooks.Stop", "hooks.events.Stop"]) +@pytest.mark.parametrize("count", [2, 3]) +def test_document_value_preserves_split_arrays_of_tables(path: str, count: int) -> None: + content = "".join( + f"[[{path}]]\nvalue = {i}\n[unrelated{i}]\nvalue = {i}\n" for i in range(count) + ) + doc = parse(content) + expected: dict[str, Any] = {} + parent = expected + *parents, key = path.split(".") + for name in parents: + parent = parent.setdefault(name, {}) + parent[key] = [{"value": i} for i in range(count)] + expected.update({f"unrelated{i}": {"value": i} for i in range(count)}) + + assert doc.unwrap() == expected + assert doc.value == expected + assert doc == expected + assert doc.as_string() == content + + +def test_document_value_preserves_wrapped_array_items() -> None: + doc = parse("[a]\nvalues = [1, 2]\n[other]\nx = 3\n[a.child]\nx = 4\n") + original = doc["a"]["values"] + values = doc.value + assert values["a"]["values"] is original + assert values["a"]["values"] == [1, 2] + assert doc.value["a"]["values"] == [1, 2] + + def test_out_of_order_table_merges_aot_fragments() -> None: # https://github.com/python-poetry/tomlkit/issues/505 content = """\ diff --git a/tomlkit/_utils.py b/tomlkit/_utils.py index c79d8790..8721f030 100644 --- a/tomlkit/_utils.py +++ b/tomlkit/_utils.py @@ -160,5 +160,9 @@ def merge_dicts(d1: dict[str, Any], d2: dict[str, Any]) -> None: for k, v in d2.items(): if k in d1 and isinstance(d1[k], dict) and isinstance(v, Mapping): merge_dicts(d1[k], dict(v)) + elif k in d1 and type(d1[k]) is list and type(v) is list: + # AoT.value creates plain lists for each fragment. Arrays retain + # their Array wrapper and must keep the usual replacement behavior. + d1[k].extend(v) else: d1[k] = d2[k]