Fix duplicated comma when removing a middle inline table element#486
Merged
frostming merged 1 commit intoJun 3, 2026
Conversation
Removing a key that is neither the first nor the last element of a parsed
inline table left both of its surrounding comma separators in the body,
producing invalid TOML such as `{a = 1, , c = 3}` that fails to re-parse.
InlineTable.as_string() now tracks whether a separator has already been
emitted for the current gap and drops the redundant comma left behind by
the removed key, so the serialized output stays valid and round-trips.
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
Removing a key that is neither the first nor the last element of a parsed inline table leaves the dangling comma separator from the deleted key in the body, producing invalid TOML that fails to re-parse.
The serialized output is not valid TOML and breaks the parse → mutate → dump round-trip.
Root cause
When a key is removed from a parsed inline table, its value becomes a
Nulland the twoWhitespaceseparators that surrounded it remain inContainer.body.InlineTable.as_string()already strips one comma in a couple of special cases (the leading separator before the first emitted key, and a trailing separator when onlyNullvalues follow), but it had no handling for the middle case: a removed interior key leaves two consecutive comma-bearing whitespace entries, so both commas are emitted and you get, ,.Fix
InlineTable.as_string()now tracks apending_separatorflag. Once a comma separator has been emitted for the current gap, the next comma-bearing whitespace entry encountered before the next real key is recognized as the redundant separator left behind by the removed key and its comma is dropped. The flag is reset whenever an actual key is emitted, so legitimate separators between surviving keys are preserved.This mirrors the existing comma-stripping pattern already used in the same method (
v.as_string().replace(",", "", 1)).Tests
Added
test_deleting_inline_table_middle_element_does_not_leave_double_separator, which deletes a middle key from a parsed inline table and asserts the result contains no, ,/,,sequence, re-parses to the expected value, and is idempotent (parse(s).as_string() == s). The test fails onmasterand passes with this change.The full suite is green:
ruff check,ruff format --check,mypy, and allpre-commithooks pass on the changed files.Notes
This is the deletion counterpart to the append fix in #477 (issue #476) and is distinct from the last-element trailing-comma case (#259) — both of those are already handled; only interior deletion was missing.