Write nested lists correctly (#5) - #12
Merged
Merged
Conversation
`as_item()` decided between an array and a table based on whether the *key* was named, not whether the value list itself was named. Any unnamed list passed as a value therefore took the table branch, where `as_kv_pairs()` inserted every element under the literal key `NA`, keeping only the last one. Derive it from the value's own names instead, mirroring `as_value()`, and turn a list of named lists into an array of tables so an item read with `get_item()` can be written back with `insert_items()`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
JosiahParry
approved these changes
Jul 31, 2026
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.
TODO: replace this line with your own framing, in your own voice.
AI-written details
Summary
as_item()chose between an array and a table from whether the key was named rather than from the value list's own names, so any unnamed list passed as a value took the table branch.as_kv_pairs()then inserted every element under the literal keyNA, keeping only the last one:as_toml(list(x = list(1, 2, 3)))produced[x]/NA = 3.0. It is now derived from the value's names, mirroring whatas_value()already does.get_item()can be inserted back withinsert_items(). This addresses the second half of handling nested list types #5 ("there isn't a clear way to massage this output as something that can be easily inserted back in as an array of tables").as_kv_pairs()errors on a non-empty unnamed list instead of emittingNAkeys. Unreachable through the public API after the change above, kept as a guard.set_prefix("\n")decor call on the array branch that was effectively unreachable before and renderedx =followed by a broken multi-line array.tests/testthat/test-nested-lists.R, plus a NEWS entry. Reading these documents already worked after 190531f; the tests cover the read shape too so handling nested list types #5 stays covered end to end.Test plan
R CMD check: clean (the only NOTE is a.gitentry from building inside a git worktree)get_item()theninsert_items()then reparse returns the same data, with the generated-file comments and untouched keys preservedgsm.appexample from the issue thread round-tripsidentical()-equaldf_as_array = FALSE, partially-named lists still errorNotes
tbls = [{ a = 1 }, { a = 2 }]) is rewritten as[[tbls]]blocks when that value is re-inserted. The data is equal and onmainthe same operation produced[tbls]/NA = { a = 2 }, so this is strictly better, but it is a formatting change in a package that advertises formatting preservation. Making the array-of-tables branch unconditional was chosen over gating it ondf_as_array, whose documented meaning does not extend to lists.dependencies = []reads asNULL, so the key disappears when written back.dependencies = ["lattice"]reads as"lattice"and writes back as a scalar string rather than a one-element array, which is a type change a consumer like rv would reject. Fixing either means changing whatget_item()andfrom_toml()return for length-0 and length-1 arrays for every user. Worth deciding separately, and until then editing a realrv.lockand writing it back is still not safe.Drafted by Claude (claude-opus-5). Reviewed by the author.