Conversation
`Array.as_string` joins its children's `as_string()` with bare concatenation and has no notion of a child that renders as a `[header]` block, so a `Table` or an `AoT` placed in an array kept its value in `unwrap()` and lost its header in the text. The result does not parse back. `InlineTable._validate_child` already rejected a `Table` (11e22ae, python-poetry#532). `Array` had no check at all, and the inline-table guard did not cover `AoT`, so the rest of the family wrote TOML nobody can read back. Add `Array._validate_child` to every mutation entry point and the missing `AoT` branch to the existing one. Behaviour change: these conversions now raise instead of silently producing a truncated document.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Putting a
Tableor anAoTinto anArrayor anInlineTableis accepted, and the object is then silently lost on rendering —unwrap()still reports it, but the text is no longer valid TOML:Two tables collapse into what reads as one element's body and the array brackets are all that is left. The same happens in an inline table (
{k = x = 1\n\nx = 2\n\n}), and for a plainTablethe header is dropped just as silently. Nothing raises, so a caller that checksunwrap()sees exactly what it put in.A table renders as its own
[header]block, so there is no value form of it to place inside[...]or{...}.InlineTablealready refuses that:_validate_childrejects aTablewithValueError("Inline tables cannot contain a table"), added in #532.Arrayhad no check at all, andInlineTable._validate_childdid not coverAoT, so the rest of the family wrote text nobody can read back. This addsArray._validate_childon every mutation entry point and the missingAoTbranch.I chose rejection over rendering a sub-table because an array element and an inline-table value are single-line value positions: producing valid output would mean silently moving the table out of its enclosing brackets, changing the document structure, and no code path here does that. The alternative would also have put a second, different policy inside the abstraction #532 just settled.
This is a behaviour change — these conversions used to succeed silently and now raise. That is the point, but it is worth saying plainly in case anyone relied on the old result.
Test:
pytest tests/test_items.py -k "table_and_aot_in_array or aot_to_inline_table"fails on8c959b5withDID NOT RAISE ValueErrorfor both new cases; the suite is 380 passed with--ignore=tests/test_toml_tests.py, that module needing thetests/toml-testsubmodule which is not checked out in my environment and so errors at collection both before and after.ruff checkandruff format --check(0.15.21, the version.pre-commit-config.yamlpins) are clean ontomlkitandtests;mypy tomlkitreports the same 5 errors before and after, none on the changed lines.Still working, and covered by the existing tests: a
Tablein aTable, aTablein anAoT, anAoTin aTable, anditem()turning a list of dicts into anArrayofInlineTable—item()keys off the parent, so a list under anArrayparent never becomes anAoT.Related to #516 but a different path: that one is
_validate_table_candidateincontainer.py, rejecting a[table]header that redefines an existing table while parsing. This is item-level construction — putting an already-built table into an array — initems.py, with no parser involved.I have not added a CHANGELOG entry; the file is organised per release and every entry cites a PR number, so tell me if you would like one and I will add it under a new section referencing this PR.
Agent Drafting Metadata
space-bunny-free)Array.as_string,InlineTable._validate_childand theTable/AoTrendering paths, wrote the guards and the two regression tests, and ran the checks quoted above. I re-ran the red-before failure on the unmodified base, the full suite, ruff at the pinned version and the mypy base comparison myself before pushing; a human review is requested before merge.AI-assisted development. Human review requested before merge.