Skip to content

Fix array of tables replacing a dotted key swallowing the next sibling (#542)#549

Open
HarperZ9 wants to merge 1 commit into
python-poetry:masterfrom
HarperZ9:fix/542-aot-captures-dotted-sibling
Open

Fix array of tables replacing a dotted key swallowing the next sibling (#542)#549
HarperZ9 wants to merge 1 commit into
python-poetry:masterfrom
HarperZ9:fix/542-aot-captures-dotted-sibling

Conversation

@HarperZ9

Copy link
Copy Markdown

Fixes #542.

Assigning an array of tables over a dotted key swallows the following sibling on round-trip:

import tomlkit
doc = tomlkit.parse("a.b = 1\nc.d = 2\n")
aot = tomlkit.aot()
t = tomlkit.table(); t["x"] = 9
aot.append(t)
doc["a"] = aot
print(tomlkit.dumps(doc))

Before:

[[a]]
x = 9
c.d = 2

c.d is captured by [[a]], so it round-trips to {"a": [{"x": 9, "c": {"d": 2}}]} and the top-level c is lost.

Cause

In Container._replace_at, the dotted_to_header guard recognises only non-super Tables, not AoTs. That guard drives the "drop the dotted prefix and move the new header past the inline entries (plain values and dotted keys) it would otherwise capture" path that already fixes the table case (#513 / #524). Because an AoT never matched it, replacing a dotted key with an array of tables left the [[a]] header in the dotted key's inline slot, capturing the next dotted sibling.

Fix

Extend dotted_to_header to also cover AoT (an array of tables always renders with its own [[header]], so it needs the same treatment as a non-super table). One-line logic change.

After:

c.d = 2

[[a]]
x = 9

Round-trips to {"c": {"d": 2}, "a": [{"x": 9}]}.

Adds test_replace_dotted_key_with_aot_keeps_following_sibling (mirrors the existing #513 table test) and a changelog entry. Full suite passes; ruff check / ruff format are clean.

python-poetry#542)

Assigning an AoT over a dotted key (e.g. `doc["a"] = aot(...)` where `a`
came from `a.b = ...`) left the new `[[a]]` header in the dotted key's
inline slot, so a following dotted sibling such as `c.d = 2` was rendered
inside the array of tables and captured on round-trip.

`_replace_at`'s `dotted_to_header` guard only recognised non-super Tables,
not AoTs, so the reposition-before-inline-siblings path that already fixes
the table case (python-poetry#513/python-poetry#524) never ran for arrays of tables. Extend the guard
to AoT. Adds a regression test mirroring the table case and a changelog entry.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AoT captures too many keys

1 participant