Skip to content

Fix invalid TOML when adding a dotted key to an inline table - #692

Open
LindseyZ1205 wants to merge 1 commit into
python-poetry:masterfrom
LindseyZ1205:fix/inline-table-dotted-key
Open

LindseyZ1205 wants to merge 1 commit into
python-poetry:masterfrom
LindseyZ1205:fix/inline-table-dotted-key

Conversation

@LindseyZ1205

Copy link
Copy Markdown

Summary

Adding a dotted key made with key() to an inline table writes invalid TOML:

>>> import tomlkit
>>> doc = tomlkit.parse("a = {b = 1}\n")
>>> doc["a"].add(tomlkit.key(["c", "d"]), 2)
>>> print(tomlkit.dumps(doc))
a = {b = 1,c. =  d = 2}

tomllib rejects it with Invalid initial character for a key part, and tomlkit's own parser with Empty key. append() and item assignment with the key do the same, and so does a new inline table ({c. = d = 2}). On a document or a table, the same key is written as c.d = 2.

The parser leaves the separator empty on every part of a dotted key but the last one, but a key made with key() keeps the default " = " on all of them. InlineTable._render_dotted() writes the separator of those parts after the dot, so it ends up as c. = . This change leaves their separator empty in Container._handle_dotted_key(), so the key has the same shape as a parsed one and is written as c.d = 2.

InlineTable.append() also puts the space before a new entry on the value. For a dotted key the value comes after the prefix, which gave {b = 1,c. d = 2} with only the change above, so the space now goes on the table that the dotted key adds.

test_add_dotted_key_to_inline_table and test_add_dotted_key_to_parsed_inline_table, next to test_add_dotted_key, cover a new and a parsed inline table, including a key under an existing dotted key and a key with three parts. Both fail on master. The full test suite passes with Python 3.14 and 3.12, and so do ruff check and ruff format --check. I found this with a script that makes random edits through the API and reads the output back with tomllib.

Duplicate Check

Agent Drafting Metadata

  • Agent: Claude Code
  • Model: Claude Opus 5.5
  • Notes:

A dotted key made with key() keeps the default " = " separator on every
part, while the parser leaves it empty on all parts but the last one.
An inline table renders those parts with their separator after the dot,
so adding such a key rendered {c. = d = 2}. Leave their separator empty
in _handle_dotted_key(), and put the space before the new entry on the
table that the dotted key adds instead of on its value, which comes
after the prefix.
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.

1 participant