Skip to content

Commit

Permalink
fix: delete keys from out of order table (#379)
Browse files Browse the repository at this point in the history
  • Loading branch information
frostming authored Aug 14, 2024
1 parent 8c1671a commit e6e5d38
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 11 deletions.
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Change Log

## [0.13.2] - 2024-08-14

### Fixed

- Fix deleting keys from an out-of-order table does not remove all table parts. ([#379](https://github.com/python-poetry/tomlkit/issues/379))

## [0.13.1] - 2024-08-14

### Fixed
Expand Down Expand Up @@ -414,7 +420,8 @@
- Fixed handling of super tables with different sections.
- Fixed raw strings escaping.

[unreleased]: https://github.com/sdispater/tomlkit/compare/0.13.1...master
[unreleased]: https://github.com/sdispater/tomlkit/compare/0.13.2...master
[0.13.2]: https://github.com/sdispater/tomlkit/releases/tag/0.13.2
[0.13.1]: https://github.com/sdispater/tomlkit/releases/tag/0.13.1
[0.13.0]: https://github.com/sdispater/tomlkit/releases/tag/0.13.0
[0.12.5]: https://github.com/sdispater/tomlkit/releases/tag/0.12.5
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "tomlkit"
version = "0.13.1"
version = "0.13.2"
description = "Style preserving TOML library"
authors = [
"Sébastien Eustace <sebastien@eustace.io>",
Expand Down
78 changes: 78 additions & 0 deletions tests/test_toml_document.py
Original file line number Diff line number Diff line change
Expand Up @@ -1109,3 +1109,81 @@ def test_item_preserves_the_order():
age = 42
"""
assert tomlkit.dumps(doc) == expected


def test_delete_out_of_order_table_key():
content = """\
[foo]
name = "foo"
[bar.a.b]
name = "bar-a-b"
[foo.a]
name = "foo-a"
[bar.a]
name = "bar-a"
[baz]
name = "baz"
[bar.a.c]
name = "bar-a-c"
"""
doc = parse(content)
del doc["bar"]["a"]
assert (
doc.as_string()
== """\
[foo]
name = "foo"
[foo.a]
name = "foo-a"
[baz]
name = "baz"
"""
)


def test_overwrite_out_of_order_table_key():
content = """\
[foo]
name = "foo"
[bar.a.b]
name = "bar-a-b"
[foo.a]
name = "foo-a"
[bar.a]
name = "bar-a"
[baz]
name = "baz"
[bar.a.c]
name = "bar-a-c"
"""
doc = parse(content)
doc["bar"]["a"] = {"name": "bar-a-updated"}
assert (
doc.as_string()
== """\
[foo]
name = "foo"
[bar.a]
name = "bar-a-updated"
[foo.a]
name = "foo-a"
[baz]
name = "baz"
"""
)
2 changes: 1 addition & 1 deletion tomlkit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
from tomlkit.api import ws


__version__ = "0.13.1"
__version__ = "0.13.2"
__all__ = [
"aot",
"array",
Expand Down
21 changes: 13 additions & 8 deletions tomlkit/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -814,7 +814,7 @@ def __init__(self, container: Container, indices: tuple[int, ...]) -> None:
table_idx = len(self._tables) - 1
for k, v in item.value.body:
self._internal_container._raw_append(k, v)
self._tables_map[k] = table_idx
self._tables_map.setdefault(k, []).append(table_idx)
if k is not None:
dict.__setitem__(self, k.key, v)

Expand All @@ -835,8 +835,12 @@ def __getitem__(self, key: Key | str) -> Any:

def __setitem__(self, key: Key | str, item: Any) -> None:
if key in self._tables_map:
table = self._tables[self._tables_map[key]]
table[key] = item
# Overwrite the first table and remove others
indices = self._tables_map[key]
while len(indices) > 1:
table = self._tables[indices.pop()]
self._remove_table(table)
self._tables[indices[0]][key] = item
elif self._tables:
table = self._tables[0]
table[key] = item
Expand All @@ -856,15 +860,16 @@ def _remove_table(self, table: Table) -> None:
break

def __delitem__(self, key: Key | str) -> None:
if key in self._tables_map:
table = self._tables[self._tables_map[key]]
if key not in self._tables_map:
raise NonExistentKey(key)

for i in reversed(self._tables_map[key]):
table = self._tables[i]
del table[key]
if not table and len(self._tables) > 1:
self._remove_table(table)
del self._tables_map[key]
else:
raise NonExistentKey(key)

del self._tables_map[key]
del self._internal_container[key]
if key is not None:
dict.__delitem__(self, key)
Expand Down

0 comments on commit e6e5d38

Please sign in to comment.