Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/fromager/dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
import os
import pathlib
import tempfile
import tomllib
import typing
import zipfile

import pyproject_hooks
import tomlkit
from packaging.metadata import Metadata
from packaging.requirements import Requirement
from packaging.utils import NormalizedName, canonicalize_name
Expand Down Expand Up @@ -492,7 +492,9 @@ def get_pyproject_contents(sdist_root_dir: pathlib.Path) -> dict[str, typing.Any
pyproject_toml_filename = sdist_root_dir / "pyproject.toml"
if not os.path.exists(pyproject_toml_filename):
return {}
return tomlkit.loads(pyproject_toml_filename.read_text())
# Read-only parse: use stdlib tomllib, not tomlkit. tomlkit rejects some
# spec-valid files (out-of-order tables), e.g. #1356.
return tomllib.loads(pyproject_toml_filename.read_text())


# From pypa/build/src/build/__main__.py
Expand Down
27 changes: 27 additions & 0 deletions tests/test_dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,33 @@ def test_get_build_backend(
assert expected_results == actual


def test_get_pyproject_contents_out_of_order_tables(tmp_path: pathlib.Path) -> None:
# Regression test for #1356: a spec-valid pyproject.toml that re-opens a
# super-table (created via dotted keys) out of order. tomlkit rejects this,
# stdlib tomllib accepts it.
tmp_path.joinpath("pyproject.toml").write_text(
textwrap.dedent("""\
[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"

[tool.ruff]
lint.extend-select = ["UP"]
lint.ignore = ["E402"]

[[tool.mypy.overrides]]
module = ["pkg.mod"]

[tool.ruff.lint.per-file-ignores]
"__init__.py" = ["F401"]
""")
)

contents = dependencies.get_pyproject_contents(tmp_path)

assert contents["build-system"]["requires"] == ["setuptools", "wheel"]


def _clean_build_artifacts(f: typing.Callable[..., None]) -> typing.Callable[..., None]:
@functools.wraps(f)
def _with_cleanup(*args: typing.Any, **kwds: typing.Any) -> None:
Expand Down
Loading