From 06236d04c082d011871920ace6494cb0b03a420a Mon Sep 17 00:00:00 2001 From: faresrafat3 Date: Thu, 1 Oct 2026 15:37:59 +0300 Subject: [PATCH 1/2] Enable intersphinx so stdlib references resolve Building the docs with `sphinx-build -n` reports many "py:class reference target not found" warnings for annotations such as collections.abc.Mapping, datetime.datetime and collections.abc.Sequence, because no intersphinx mapping is configured (see #192). Add the sphinx.ext.intersphinx extension with the Python inventory. Warnings under -n drop from 55 to 31. The remainder are project-internal references (tomlkit.items.ItemT, tomlkit.container.Container, E, Encoder) that are not part of this change. Fixes #192 (partially). --- docs/conf.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/conf.py b/docs/conf.py index cbb9ee44..cf4e8159 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -36,8 +36,17 @@ # ones. extensions = [ "sphinx.ext.autodoc", + "sphinx.ext.intersphinx", ] +# Resolve references to the standard library and other projects, so that +# annotations such as collections.abc.Mapping or datetime.datetime link to +# their documentation instead of producing "reference target not found" +# warnings under `sphinx-build -n`. +intersphinx_mapping = { + "python": ("https://docs.python.org/3", None), +} + # Add any paths that contain templates here, relative to this directory. templates_path = ["_templates"] From 37ccab6d37d534a894bbd73bc1367265b672c440 Mon Sep 17 00:00:00 2001 From: faresrafat3 Date: Thu, 1 Oct 2026 16:35:28 +0300 Subject: [PATCH 2/2] Fix regression parsing out-of-order tables split by another table A document where a table has an out-of-order child, its concrete parent is declared afterwards, and a later sibling child is separated by an unrelated table was rejected with 'Key already exists', although tomllib and tomlkit 0.13.3/0.14.0/0.15.0 all accept it: [tool.ruff] [tool.ruff.lint.a] [tool.ruff.lint] [[tool.poetry.source]] [tool.ruff.lint.b] When a key is defined out of order, Container.item() returns an OutOfOrderTableProxy rather than the Table itself, because the key maps to several body positions. _validate_table_candidate compared the candidate against that proxy with isinstance(existing, (Table, AoT)), which is False for a proxy, so a valid table-vs-table extension was reported as a table-vs-scalar type conflict and raised KeyAlreadyPresent. Skip the type comparison when the existing entry is an out-of-order proxy; its fragments are validated by the proxy itself. Fixes #571. --- tests/test_toml_document.py | 32 ++++++++++++++++++++++++++++++++ tomlkit/container.py | 7 +++++++ 2 files changed, 39 insertions(+) diff --git a/tests/test_toml_document.py b/tests/test_toml_document.py index 116de352..cd749753 100644 --- a/tests/test_toml_document.py +++ b/tests/test_toml_document.py @@ -664,6 +664,38 @@ def test_valid_out_of_order_independent_tables() -> None: assert doc.as_string() == "[a]\nx=1\n[zz]\n[a.b]\nc=1\n" +def test_out_of_order_child_split_by_unrelated_table() -> None: + # https://github.com/python-poetry/tomlkit/issues/571 + # An out-of-order child, its concrete parent declared afterwards, and a + # later sibling child separated by an unrelated table. tomllib accepts + # this, and so did tomlkit 0.13.3/0.14.0/0.15.0. + source = """\ +[tool.ruff] +[tool.ruff.lint.a] +[tool.ruff.lint] +[[tool.poetry.source]] +[tool.ruff.lint.b] +""" + doc = parse(source) + assert doc.unwrap() == { + "tool": { + "ruff": { + "lint": {"a": {}, "b": {}}, + }, + "poetry": {"source": [{}]}, + }, + } + assert doc.as_string() == source + + +def test_out_of_order_child_split_at_depth() -> None: + # Same shape, deeper and without the array-of-tables in between. + source = "[a.b]\n[a.b.c.d]\n[a.b.c]\n[z]\n[a.b.c.e]\n" + doc = parse(source) + assert doc.unwrap() == {"a": {"b": {"c": {"d": {}, "e": {}}}}, "z": {}} + assert doc.as_string() == source + + def test_set_value_on_out_of_order_table_with_empty_concrete_part() -> None: # A super table defined after its sub-table (the "defining a super-table # afterward is ok" spec example) leaves an empty concrete `[x]` part. diff --git a/tomlkit/container.py b/tomlkit/container.py index 2f0fc034..925934ac 100644 --- a/tomlkit/container.py +++ b/tomlkit/container.py @@ -428,6 +428,13 @@ def _validate_table_candidate(self, current: Table, candidate: Table) -> None: if k in current.value._map: existing = current.value.item(k) + # An OutOfOrderTableProxy stands for one or more tables whose + # definitions are spread through the document; it is not a + # `Table` instance, so the isinstance comparison below would + # wrongly report a type conflict for a valid out-of-order + # document. Its contents are already validated by the proxy. + if isinstance(existing, OutOfOrderTableProxy): + continue if isinstance(existing, (Table, AoT)) != isinstance(v, (Table, AoT)): raise KeyAlreadyPresent(k) if k.is_dotted():