Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
### Fixed

- Arithmetic and `replace()` results for `Integer`, `Float`, `String`, `DateTime`, `Date` and `Time` no longer share the original item's `Trivia`, so changing the result's comment or indentation no longer rewrites the item still stored in the document.
- Fix a dotted key made with `key()` and added to an inline table (e.g. `table.add(key(["c", "d"]), 2)`) being written as invalid TOML such as `{c. = d = 2}`; it is now written as `{c.d = 2}`.

## [0.15.2] - 2026-10-16

Expand Down
15 changes: 15 additions & 0 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,21 @@ def test_add_dotted_key() -> None:
assert table.as_string() == "foo.bar = 1\n"


def test_add_dotted_key_to_inline_table() -> None:
table = tomlkit.inline_table()
table.add(tomlkit.key(["foo", "bar"]), 1)
table[tomlkit.key(["foo", "baz"])] = 2
assert table.as_string() == "{foo.bar = 1, foo.baz = 2}"


def test_add_dotted_key_to_parsed_inline_table() -> None:
doc = parse("a = {b.c = 1}\n")
doc["a"].add(tomlkit.key(["b", "d"]), 2)
doc["a"].append(tomlkit.key(["e", "f", "g"]), 3)
assert doc.as_string() == "a = {b.c = 1, b.d = 2, e.f.g = 3}\n"
assert doc == {"a": {"b": {"c": 1, "d": 2}, "e": {"f": {"g": 3}}}}


def test_key_with_single_element_list_is_a_single_key() -> None:
# Regression test for
# https://github.com/python-poetry/tomlkit/issues/430: a one-element key
Expand Down
4 changes: 4 additions & 0 deletions tomlkit/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,10 +210,14 @@ def _handle_dotted_key(self, key: Key, value: Item) -> None:
if isinstance(value, (Table, AoT)):
raise TOMLKitError("Can't add a table to a dotted key")
name, *mid, last = key
# The parts before the last one are followed by a dot, not by the
# separator, so leave theirs empty as the parser does
name._dotted = True
name.sep = ""
table = current = Table(Container(True), Trivia(), False, is_super_table=True)
for _name in mid:
_name._dotted = True
_name.sep = ""
new_table = Table(Container(True), Trivia(), False, is_super_table=True)
current.append(_name, new_table)
current = new_table
Expand Down
17 changes: 14 additions & 3 deletions tomlkit/items.py
Original file line number Diff line number Diff line change
Expand Up @@ -2088,13 +2088,24 @@ def append(self, key: Key | str | None, _item: Any) -> InlineTable:

self._validate_child(_item)

needs_indent = False
if not isinstance(_item, (Whitespace, Comment)):
if not _item.trivia.indent and len(self._value) > 0 and not self._new:
_item.trivia.indent = " "
needs_indent = (
not _item.trivia.indent and len(self._value) > 0 and not self._new
)
if _item.trivia.comment:
_item.trivia.comment = ""

self._value.append(key, _item)
if isinstance(key, Key) and key.is_multi():
# The value of a dotted key is rendered after the key (``a.b = 1``),
# so the space goes on the table that the key adds as a new entry
self._value.append(key, _item)
if needs_indent:
self._value.body[-1][1].trivia.indent = " "
else:
if needs_indent:
_item.trivia.indent = " "
self._value.append(key, _item)

if isinstance(key, Key):
key = key.key
Expand Down
Loading