tomlkit
tomlkit copied to clipboard
out of order sections causing issues
When there are sections defined out of order, it seems tomlkit
does not like it. Original issue was reported at https://github.com/python-poetry/poetry/issues/4718.
The following code runs without issues, however does not modify the toml. Using content.value_insert_after()
causes AttributeError: 'dict' object has no attribute '_insert_after'
.
If we remove build-system
from the toml, the code below raises AttributeError: 'Table' object has no attribute '_insert_after'
. However using content.value
succeeds with the right results.
reproducer.py
import tomlkit
TOML = tomlkit.parse("""\
[tool.poetry]
name = "foobar"
version = "0.1.0"
description = ""
readme = "README.md"
[tool.poetry.dependencies]
python = "^3.10"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
[tool.poetry.plugins]
""")
if __name__ == '__main__':
content = TOML["tool"]["poetry"]
content._insert_after("dependencies", "group", tomlkit.table(is_super_table=True))
content["group"]["one"] = tomlkit.table(is_super_table=True)
content["group"]["one"]["dependencies"] = tomlkit.table()
print(TOML.as_string())
Here is a test case that reproduces the issue.
def test_string_output_order_is_preserved_for_out_of_order_tables_with_insert_after():
content_upper = """
[tool.poetry]
name = "foo"
[tool.poetry.dependencies]
python = "^3.6"
"""
content_lower = """
[build-system]
requires = ["poetry-core"]
backend = "poetry.core.masonry.api"
[tool.poetry.build]
"""
content_added = """
[tool.poetry.group.bar.dependencies]"""
doc = parse(content_upper + content_lower)
doc["tool"]["poetry"].value._insert_after(
"dependencies", "group", tomlkit.table(True)
)
groups = doc["tool"]["poetry"]["group"]
groups["bar"] = tomlkit.table(True)
groups["bar"]["dependencies"] = tomlkit.table()
assert doc.as_string() == content_upper + content_added + content_lower
@frostming any chance I can get a pointer on where to fix this? Happy to do the leg work.
You are trying to get the DOM element(A Container
in tomlkit) of the table via .value
while for a OutOfOrderTableProxy
, the .value
returns an intermediate helper Container
that is created when building the proxy, hence any modification won't reflect to the original document.
To fix it, you need to make the modification on one of the underlying tables that are combined by the OutOfOrderTableProxy
. See the example here. However, that needs to add those underscored methods to both OutOfOrderTableProxy
, Table
, and perhaps InlineTable
.
I'm having trouble following the example here. Is there any more documentation or examples on how to resolve these out of order problems?
I'm trying to update a tool.<TOOL_NAME>
section but I can't seem to get it right.
Desired
[tool.ruff]
target-version = "py38"
line-length = 120
lint.select = ["F", "ASYNC", "RUFF", "B", "S", "PTH", "W", "E"]
lint.ignore = ["W191", "E111"]
Actual
[tool.ruff]
target-version = "py38"
line-length = 120
[tool.ruff.lint]
tool.ruff.lint.select = ["F", "ASYNC", "RUFF", "B", "S", "PTH", "W", "E"]
tool.ruff.lint.ignore = ["W191", "E111"]
I'm having trouble following the example here.
Sorry, what code you are trying?