Skip to content

Merge an out-of-order fragment that extends an AoT element - #584

Open
dchaudhari7177 wants to merge 1 commit into
python-poetry:masterfrom
dchaudhari7177:fix/aot-super-table-fragment
Open

Merge an out-of-order fragment that extends an AoT element#584
dchaudhari7177 wants to merge 1 commit into
python-poetry:masterfrom
dchaudhari7177:fix/aot-super-table-fragment

Conversation

@dchaudhari7177

Copy link
Copy Markdown

Fixes #577.

Problem

content = """\
[[y.a]]
[b.d.x]
[[y.a.c]]
"""
doc = parse(content)
assert doc.as_string() == content   # passes
doc.unwrap()                        # KeyAlreadyPresent: Key "a" already exists

tomllib reads this as {"y": {"a": [{"c": [{}]}]}, "b": {"d": {"x": {}}}}. Parsing and rendering are fine; only the read path fails.

Cause

[b.d.x] splits y, so reading it builds an OutOfOrderTableProxy over the two y fragments. The final header extends the last element of the existing y.a array rather than appending a new element, so the second a fragment arrives at the proxy as an implicit super table holding c — not as another AoT.

_merge_aot_fragment only handles AoT + AoT. It returned None for the super-table shape, the caller fell through to _raw_append, and that refused a as a duplicate key.

Fix

Handle the super-table shape in the same place: copy the array's last element, merge the fragment's body into the copy, and hand back a new AoT. Copying is what keeps the fragments the document renders from untouched — the same reason the existing AoT + AoT path builds a new AoT instead of mutating one.

The guard stays narrow: only a super table (never a concrete [y.a] redefinition) and only when the array actually has an element, so genuine duplicates still raise.

Tests

  • test_out_of_order_table_merges_aot_element_extension — the reported document, with values on both sides, checking round-trip, unwrap() against the tomllib shape, and indexed access.
  • test_out_of_order_table_extends_last_of_several_aot_elements — two elements before the split, confirming the extension lands on the last one only.

I also checked the neighbouring shapes against tomllib (a plain out-of-order AoT split, [y.a.c] as a plain table rather than an AoT, and two [[y.a.c]] headers separated by another table); all agree.

Full suite passes (1053 tests).

🤖 Generated with Claude Code

    [[y.a]]
    [b.d.x]
    [[y.a.c]]

parses and round-trips, but doc["y"] or doc.unwrap() raised
`Key "a" already exists`.

`[b.d.x]` makes `y` out of order, so its parts go through
OutOfOrderTableProxy. The last header extends the last element of the
existing `y.a` array, which means the second `a` fragment arrives as an
implicit super table rather than as another AoT.
_merge_aot_fragment only recognised AoT + AoT, returned None, and
_raw_append then refused the duplicate key.

Handle the super-table shape too: copy the array's last element, merge
the fragment's body into the copy, and present a new AoT. Copying keeps
the fragments the document renders from untouched, as the AoT + AoT path
already does.

Fixes python-poetry#577
@dimbleby

dimbleby commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

why is this better or worse than the existing pull request #578?

@dchaudhari7177 you should likely have your bot check for already-open pull requests before creating new ones

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.

unwrap raises KeyAlreadyPresent for an out-of-order AoT element extension

2 participants