Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions tests/test_toml_document.py
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,13 @@ def test_valid_out_of_order_independent_tables() -> None:
assert doc.as_string() == "[a]\nx=1\n[zz]\n[a.b]\nc=1\n"


def test_valid_nested_out_of_order_table_after_unrelated_table() -> None:
content = "[a]\n[a.b.c]\n[a.b]\n[[zz]]\n[a.b.d]\n"
doc = parse(content)
assert doc.unwrap() == {"a": {"b": {"c": {}, "d": {}}}, "zz": [{}]}
assert doc.as_string() == content


def test_set_value_on_out_of_order_table_with_empty_concrete_part() -> None:
# A super table defined after its sub-table (the "defining a super-table
# afterward is ok" spec example) leaves an empty concrete `[x]` part.
Expand Down
29 changes: 17 additions & 12 deletions tomlkit/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -423,19 +423,24 @@ def _validate_table_candidate(self, current: Table, candidate: Table) -> None:
continue

if k in current.value._map:
existing = current.value.item(k)
if isinstance(existing, (Table, AoT)) != isinstance(v, (Table, AoT)):
raise KeyAlreadyPresent(k)
if k.is_dotted():
raise TOMLKitError("Redefinition of an existing table")
if isinstance(existing, Table) and isinstance(v, Table):
if not existing.is_super_table() and not v.is_super_table():
# Both sides are concrete `[table]` definitions of the
# same name; the table is declared twice.
index = current.value._map[k]
indices = index if isinstance(index, tuple) else (index,)
for i in indices:
existing = current.value._body[i][1]
if isinstance(existing, (Table, AoT)) != isinstance(
v, (Table, AoT)
):
raise KeyAlreadyPresent(k)
# One side is still an implicit/super table, so a duplicate
# (if any) is nested deeper - keep checking the subtree.
self._validate_table_candidate(existing, v)
if k.is_dotted():
raise TOMLKitError("Redefinition of an existing table")
if isinstance(existing, Table) and isinstance(v, Table):
if not existing.is_super_table() and not v.is_super_table():
# Both sides are concrete `[table]` definitions of the
# same name; the table is declared twice.
raise KeyAlreadyPresent(k)
# One side is still an implicit/super table, so a duplicate
# (if any) is nested deeper - keep checking the subtree.
self._validate_table_candidate(existing, v)
continue

if not k.is_dotted():
Expand Down