From 28fe6ec7386e3923a3e87efae8ab580138f6fcbc Mon Sep 17 00:00:00 2001 From: Frost Ming Date: Wed, 14 Aug 2024 10:04:50 +0800 Subject: [PATCH] fix: Empty table dumped when number of subtables > 1 (#378) Fixes #377 Signed-off-by: Frost Ming --- CHANGELOG.md | 1 + tests/test_items.py | 13 +++++++++++++ tomlkit/items.py | 30 ++++++++++++++++-------------- 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e6fa61..77e63d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Fixed - Fix the `Table.is_super_table()` check for tables with dotted key as the only child. ([#374](https://github.com/python-poetry/tomlkit/issues/374)) +- Count table as a super table if it has children and all children are either tables or arrays of tables. ([#377](https://github.com/python-poetry/tomlkit/issues/377)) ## [0.13.0] - 2024-07-10 diff --git a/tests/test_items.py b/tests/test_items.py index 4a82948..8bcc5fe 100644 --- a/tests/test_items.py +++ b/tests/test_items.py @@ -993,3 +993,16 @@ def test_serialize_table_with_dotted_key(): parent = api.table() parent.add("a", child) assert parent.as_string() == "[a]\nb.c = 1\n" + + +def test_not_showing_parent_header_for_super_table(): + doc = api.document() + + def add_table(parent, name): + parent.add(name, api.table()) + return parent[name] + + root = add_table(doc, "root") + add_table(root, "first") + add_table(root, "second") + assert doc.as_string() == "[root.first]\n\n[root.second]\n" diff --git a/tomlkit/items.py b/tomlkit/items.py index 538b72e..b46679b 100644 --- a/tomlkit/items.py +++ b/tomlkit/items.py @@ -1621,21 +1621,23 @@ def is_super_table(self) -> bool: If true, it won't appear in the TOML representation.""" if self._is_super_table is not None: return self._is_super_table - # If the table has only one child and that child is a table, then it is a super table. - if len(self) != 1: + if not self: return False - k, only_child = next(iter(self.items())) - if not isinstance(k, Key): - k = SingleKey(k) - index = self.value._map[k] - if isinstance(index, tuple): - return False - real_key = self.value.body[index][0] - return ( - isinstance(only_child, (Table, AoT)) - and real_key is not None - and not real_key.is_dotted() - ) + # If the table has children and all children are tables, then it is a super table. + for k, child in self.items(): + if not isinstance(k, Key): + k = SingleKey(k) + index = self.value._map[k] + if isinstance(index, tuple): + return False + real_key = self.value.body[index][0] + if ( + not isinstance(child, (Table, AoT)) + or real_key is None + or real_key.is_dotted() + ): + return False + return True def as_string(self) -> str: return self._value.as_string()