reject a table redefined after its parent table header#516
Conversation
Hmm, we are using toml-test suite but why it isn't caught? |
|
The suite just does not have a case with this shape. Its table-redefinition cases all re-declare the parent/super header, not the child:
tomlkit already rejects all of those. The gap is when the child header is the repeated one with the parent declared in between, like Since toml-test is a submodule we do not own, I added the regression cases in |
`Container._validate_table_candidate` rejected valid TOML: when a deep header
like `[a.b.c]` makes `a.b` an implicit super-table, reopening `[a]` and
extending `a.b` via a dotted key (`b.z = 1`) was rejected with "Redefinition of
an existing table". No table is defined twice -- `a.b` only gains a new key --
and stdlib `tomllib` (the validity oracle the tests already use) accepts it,
producing `{'a': {'b': {'c': {}, 'z': 1}}}`.
The `if k.is_dotted(): raise` guard fired before the super-table recursion that
follows it, so it never got the chance to validate the subtree for a real
conflict. Only reject the dotted case when the existing entry is *not* a super
table; otherwise fall through to the existing recursion, which raises only on an
actual redefinition. The concrete-table case (`[a.b]` then `[a]` `b.z = 1`)
stays rejected, matching tomllib and the redefinition rejections from python-poetry#516/python-poetry#530.
Adds a regression test next to the sibling out-of-order tests; it is red before
the fix (ParseError) and green after. Full suite passes (372).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Summary
Container.appendsends a concrete[table]header that lands inside an existing implicit/super table through_validate_table_candidate, which only flagged a child key on a type change or a dotted-key redefinition.[a.b]/[a]/[a.b], and the deeper[a.b.c]/[a]/[a.b.c]) was merged silently instead of rejected, whiletomlliband the toml-test suite treat these as declaring the same table twice._validate_table_candidatenow raises when the existing child and the candidate child are both concrete (non-super) tables, and recurses through matching super tables so a duplicate nested deeper is caught as well. Valid out-of-order tables (a new sibling subtable, or extending a table with a deeper header) keep parsing, and the existing tests plus the toml-test 1.0/1.1 suites pass.Agent Drafting Metadata