Skip to content

Commit bcf1185

Browse files
author
Ben Rowland
committed
fix: change metadata entrypoints to take pyproject contents not path
Also changes the name of the entrypoint group to scikit_build.metadata. This commit also changes the SettingsReader to load from a pyproject dict rather than loading from file, this saves parsing the file multiple times to access the metadata as well. A new class method `from_file()` provides the previous functionality of loading from a path.
1 parent af5651c commit bcf1185

File tree

10 files changed

+74
-51
lines changed

10 files changed

+74
-51
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ Examples = "https://github.com/scikit-build/scikit-build-core/tree/main/tests/pa
9191
cmake_extensions = "scikit_build_core.setuptools.extension:cmake_extensions"
9292
cmake_source_dir = "scikit_build_core.setuptools.extension:cmake_source_dir"
9393

94-
[project.entry-points.skbuild]
94+
[project.entry-points."scikit_build.metadata"]
9595
setuptools_scm = "scikit_build_core.settings.metadata:setuptools_scm_version"
9696
fancy_pypi_readme = "scikit_build_core.settings.metadata:fancy_pypi_readme"
9797

src/scikit_build_core/build/sdist.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,8 @@
88
import tarfile
99
from pathlib import Path
1010

11-
from pyproject_metadata import StandardMetadata
12-
1311
from .._compat import tomllib
12+
from ..settings.metadata import get_standard_metadata
1413
from ..settings.skbuild_read_settings import SettingsReader
1514
from ._file_processor import each_unignored_file
1615
from ._init import setup_logging
@@ -69,23 +68,23 @@ def build_sdist(
6968
sdist_directory: str,
7069
config_settings: dict[str, list[str] | str] | None = None,
7170
) -> str:
72-
settings_reader = SettingsReader(Path("pyproject.toml"), config_settings or {})
71+
with Path("pyproject.toml").open("rb") as f:
72+
pyproject = tomllib.load(f)
73+
74+
settings_reader = SettingsReader(pyproject, config_settings or {})
7375
settings = settings_reader.settings
7476
setup_logging(settings.logging.level)
7577

7678
settings_reader.validate_may_exit()
7779

7880
sdist_dir = Path(sdist_directory)
7981

80-
with Path("pyproject.toml").open("rb") as f:
81-
pyproject = tomllib.load(f)
82-
8382
reproducible = settings.sdist.reproducible
8483
timestamp = get_reproducible_epoch() if reproducible else None
8584

85+
metadata = get_standard_metadata(pyproject, settings)
8686
# Using deepcopy here because of a bug in pyproject-metadata
8787
# https://github.com/FFY00/python-pyproject-metadata/pull/49
88-
metadata = StandardMetadata.from_pyproject(pyproject)
8988
pkg_info = bytes(copy.deepcopy(metadata).as_rfc822())
9089

9190
srcdirname = f"{metadata.name}-{metadata.version}"

src/scikit_build_core/build/wheel.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from packaging.version import Version
1010

1111
from .. import __version__
12+
from .._compat import tomllib
1213
from .._logging import logger, rich_print
1314
from ..builder.builder import Builder
1415
from ..builder.wheel_tag import WheelTag
@@ -70,14 +71,17 @@ def _build_wheel_impl(
7071
"""
7172
Build a wheel or just prepare metadata (if wheel dir is None).
7273
"""
74+
pyproject_path = Path("pyproject.toml")
75+
with pyproject_path.open("rb") as ft:
76+
pyproject = tomllib.load(ft)
7377

74-
settings_reader = SettingsReader(Path("pyproject.toml"), config_settings or {})
78+
settings_reader = SettingsReader(pyproject, config_settings or {})
7579
settings = settings_reader.settings
7680
setup_logging(settings.logging.level)
7781

7882
settings_reader.validate_may_exit()
7983

80-
metadata = get_standard_metadata(Path("pyproject.toml"), settings)
84+
metadata = get_standard_metadata(pyproject, settings)
8185

8286
if metadata.version is None:
8387
msg = "project.version is not statically specified, must be present currently"

src/scikit_build_core/builder/get_requires.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ def is_known_platform(platforms: frozenset[str]) -> bool:
4242
def cmake_ninja_for_build_wheel(
4343
config_settings: Mapping[str, str | list[str]] | None = None
4444
) -> list[str]:
45-
settings = SettingsReader(Path("pyproject.toml"), config_settings or {}).settings
45+
settings = SettingsReader.from_file(
46+
Path("pyproject.toml"), config_settings or {}
47+
).settings
4648

4749
packages = []
4850
cmake_min = Version(settings.cmake.minimum_version)
Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
from __future__ import annotations
22

3-
import pathlib
43
import warnings
4+
from pathlib import Path
5+
from typing import Any
56

67
from pyproject_metadata import StandardMetadata
78

8-
from .._compat import importlib, tomllib
9+
from .._compat import importlib
910
from ..settings.skbuild_model import ScikitBuildSettings
1011

1112
__all__ = ["setuptools_scm_version", "fancy_pypi_readme", "get_standard_metadata"]
@@ -15,24 +16,23 @@ def __dir__() -> list[str]:
1516
return __all__
1617

1718

18-
def setuptools_scm_version(pyproject_path: pathlib.Path) -> str:
19+
def setuptools_scm_version(_pyproject_dict: dict[str, Any]) -> str:
20+
# this is a placeholder version of this function, waiting for the release
21+
# of vcs-versioning and an improved public interface
1922
from setuptools_scm import Configuration, _get_version
2023

21-
config = Configuration.from_file(str(pyproject_path))
24+
config = Configuration.from_file(str(Path("pyproject.toml")))
2225
version: str = _get_version(config)
2326

2427
return version
2528

2629

27-
def fancy_pypi_readme(pyproject_path: pathlib.Path) -> str | dict[str, str | None]:
30+
def fancy_pypi_readme(pyproject_dict: dict[str, Any]) -> str | dict[str, str | None]:
2831
from hatch_fancy_pypi_readme._builder import build_text
2932
from hatch_fancy_pypi_readme._config import load_and_validate_config
3033

31-
with pyproject_path.open("rb") as ft:
32-
pyproject = tomllib.load(ft)
33-
3434
config = load_and_validate_config(
35-
pyproject["tool"]["hatch"]["metadata"]["hooks"]["fancy-pypi-readme"]
35+
pyproject_dict["tool"]["hatch"]["metadata"]["hooks"]["fancy-pypi-readme"]
3636
)
3737

3838
return {
@@ -42,16 +42,14 @@ def fancy_pypi_readme(pyproject_path: pathlib.Path) -> str | dict[str, str | Non
4242

4343

4444
def get_standard_metadata(
45-
pyproject_path: pathlib.Path, settings: ScikitBuildSettings
45+
pyproject_dict: dict[str, Any], settings: ScikitBuildSettings
4646
) -> StandardMetadata:
47-
with pyproject_path.open("rb") as ft:
48-
pyproject = tomllib.load(ft)
49-
metadata = StandardMetadata.from_pyproject(pyproject)
47+
metadata = StandardMetadata.from_pyproject(pyproject_dict)
5048

5149
# handle any dynamic metadata
5250
# start by collecting all the scikit-build entrypoints
5351
eps: importlib.metadata.EntryPoints = importlib.metadata.entry_points(
54-
group="skbuild"
52+
group="scikit_build.metadata"
5553
)
5654
for field, ep_name in settings.metadata.items():
5755
if field not in metadata.dynamic:
@@ -67,9 +65,9 @@ def get_standard_metadata(
6765
# would be better to update the metadata directly but this is
6866
# currently not supported by pyproject_metadata
6967
# metadata.__setattr__(field, ep.load()(pyproject_path)
70-
pyproject["project"][field] = ep.load()(pyproject_path)
71-
pyproject["project"]["dynamic"].remove(field)
68+
pyproject_dict["project"][field] = ep.load()(pyproject_dict)
69+
pyproject_dict["project"]["dynamic"].remove(field)
7270

7371
# if pyproject-metadata supports updates, we won't need this line anymore
74-
metadata = StandardMetadata.from_pyproject(pyproject)
72+
metadata = StandardMetadata.from_pyproject(pyproject_dict)
7573
return metadata

src/scikit_build_core/settings/skbuild_read_settings.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import sys
55
from collections.abc import Generator, Mapping
66
from pathlib import Path
7+
from typing import Any
78

89
from packaging.version import Version
910

@@ -24,13 +25,10 @@ def __dir__() -> list[str]:
2425
class SettingsReader:
2526
def __init__(
2627
self,
27-
pyproject_toml: Path,
28+
pyproject: dict[str, Any],
2829
config_settings: Mapping[str, str | list[str]],
2930
verify_conf: bool = True,
3031
) -> None:
31-
with pyproject_toml.open("rb") as f:
32-
pyproject = tomllib.load(f)
33-
3432
self.sources = SourceChain(
3533
EnvSource("SKBUILD"),
3634
ConfSource(settings=config_settings, verify=verify_conf),
@@ -85,3 +83,15 @@ def validate_may_exit(self) -> None:
8583
self.print_suggestions()
8684
raise SystemExit(7)
8785
logger.warning("Unrecognized options: {}", ", ".join(unrecognized))
86+
87+
@classmethod
88+
def from_file(
89+
cls,
90+
pyproject_path: Path,
91+
config_settings: Mapping[str, str | list[str]],
92+
verify_conf: bool = True,
93+
) -> SettingsReader:
94+
with pyproject_path.open("rb") as f:
95+
pyproject = tomllib.load(f)
96+
97+
return cls(pyproject, config_settings, verify_conf)

src/scikit_build_core/setuptools/extension.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def build_extension(self, ext: setuptools.Extension) -> None:
5757
if build_temp.exists():
5858
shutil.rmtree(build_temp)
5959

60-
settings = SettingsReader(Path("pyproject.toml"), {}).settings
60+
settings = SettingsReader.from_file(Path("pyproject.toml"), {}).settings
6161

6262
cmake = CMake.default_search(
6363
minimum_version=Version(settings.cmake.minimum_version)
@@ -118,7 +118,7 @@ def build_extension(self, ext: setuptools.Extension) -> None:
118118
def cmake_extensions(
119119
dist: Distribution, attr: Literal["cmake_extensions"], value: list[CMakeExtension]
120120
) -> None:
121-
settings = SettingsReader(Path("pyproject.toml"), {}).settings
121+
settings = SettingsReader.from_file(Path("pyproject.toml"), {}).settings
122122

123123
assert attr == "cmake_extensions"
124124
assert value

tests/test_dynamic_metadata.py

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import pyproject_metadata
99
import pytest
1010

11-
from scikit_build_core._compat import importlib
11+
from scikit_build_core._compat import importlib, tomllib
1212
from scikit_build_core.build import build_wheel
1313
from scikit_build_core.settings.metadata import get_standard_metadata
1414
from scikit_build_core.settings.skbuild_read_settings import SettingsReader
@@ -56,22 +56,25 @@ def mock_ep(**_):
5656
def test_dynamic_metadata(monkeypatch):
5757
monkeypatch.chdir(DYNAMIC)
5858

59-
settings_reader = SettingsReader(Path("pyproject.toml"), {})
59+
with Path("pyproject.toml").open("rb") as ft:
60+
pyproject = tomllib.load(ft)
61+
settings_reader = SettingsReader(pyproject, {})
6062
settings = settings_reader.settings
6163

6264
settings_reader.validate_may_exit()
6365

64-
metadata = get_standard_metadata(Path("pyproject.toml"), settings)
66+
metadata = get_standard_metadata(pyproject, settings)
6567

6668
assert str(metadata.version) == "0.0.2"
6769
assert metadata.license == pyproject_metadata.License("MIT License", None)
6870
assert metadata.readme == pyproject_metadata.Readme("Some text", None, "text/x-rst")
6971

7072

71-
def test_fancy_metadata(tmp_path, monkeypatch):
73+
def test_plugin_metadata(tmp_path, monkeypatch):
7274
build_dir = tmp_path / "build"
75+
build_dir.mkdir()
7376

74-
shutil.copytree(DYNAMIC, build_dir)
77+
shutil.copy(DYNAMIC / "plugin_project.toml", build_dir / "pyproject.toml")
7578
monkeypatch.chdir(build_dir)
7679

7780
repo = git.repo.base.Repo.init(build_dir, initial_branch="main")
@@ -81,12 +84,14 @@ def test_fancy_metadata(tmp_path, monkeypatch):
8184
repo.index.commit("first commit")
8285
repo.create_tag("v0.1.0", message="initial commit")
8386

84-
settings_reader = SettingsReader(Path("fancy_project.toml"), {})
87+
with Path("pyproject.toml").open("rb") as ft:
88+
pyproject = tomllib.load(ft)
89+
settings_reader = SettingsReader(pyproject, {})
8590
settings = settings_reader.settings
8691

8792
settings_reader.validate_may_exit()
8893

89-
metadata = get_standard_metadata(Path("fancy_project.toml"), settings)
94+
metadata = get_standard_metadata(pyproject, settings)
9095

9196
assert str(metadata.version) == "0.1.0"
9297
assert metadata.readme == pyproject_metadata.Readme(
@@ -96,24 +101,29 @@ def test_fancy_metadata(tmp_path, monkeypatch):
96101

97102
def test_faulty_metadata(monkeypatch):
98103
monkeypatch.chdir(DYNAMIC)
99-
settings_reader = SettingsReader(Path("faulty_project.toml"), {})
104+
105+
with Path("faulty_project.toml").open("rb") as ft:
106+
pyproject = tomllib.load(ft)
107+
settings_reader = SettingsReader(pyproject, {})
100108
settings = settings_reader.settings
101109

102110
settings_reader.validate_may_exit()
103111

104112
with pytest.raises(KeyError):
105-
get_standard_metadata(Path("faulty_project.toml"), settings)
113+
get_standard_metadata(pyproject, settings)
106114

107115

108116
def test_warn_metadata(monkeypatch):
109117
monkeypatch.chdir(DYNAMIC)
110-
settings_reader = SettingsReader(Path("warn_project.toml"), {})
118+
with Path("warn_project.toml").open("rb") as ft:
119+
pyproject = tomllib.load(ft)
120+
settings_reader = SettingsReader(pyproject, {})
111121
settings = settings_reader.settings
112122

113123
settings_reader.validate_may_exit()
114124

115125
with pytest.warns():
116-
get_standard_metadata(Path("warn_project.toml"), settings)
126+
get_standard_metadata(pyproject, settings)
117127

118128

119129
@pytest.mark.compile()

tests/test_skbuild_settings.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ def test_skbuild_settings_default(tmp_path):
1515

1616
config_settings: dict[str, list[str] | str] = {}
1717

18-
settings_reader = SettingsReader(pyproject_toml, config_settings)
18+
settings_reader = SettingsReader.from_file(pyproject_toml, config_settings)
1919
settings = settings_reader.settings
2020
assert list(settings_reader.unrecognized_options()) == []
2121

@@ -70,7 +70,7 @@ def test_skbuild_settings_envvar(tmp_path, monkeypatch):
7070

7171
config_settings: dict[str, list[str] | str] = {}
7272

73-
settings_reader = SettingsReader(pyproject_toml, config_settings)
73+
settings_reader = SettingsReader.from_file(pyproject_toml, config_settings)
7474
settings = settings_reader.settings
7575
assert list(settings_reader.unrecognized_options()) == []
7676

@@ -126,7 +126,7 @@ def test_skbuild_settings_config_settings(tmp_path, monkeypatch):
126126
"build-dir": "a/b/c",
127127
}
128128

129-
settings_reader = SettingsReader(pyproject_toml, config_settings)
129+
settings_reader = SettingsReader.from_file(pyproject_toml, config_settings)
130130
settings = settings_reader.settings
131131
assert list(settings_reader.unrecognized_options()) == []
132132

@@ -186,7 +186,7 @@ def test_skbuild_settings_pyproject_toml(tmp_path, monkeypatch):
186186

187187
config_settings: dict[str, list[str] | str] = {}
188188

189-
settings_reader = SettingsReader(pyproject_toml, config_settings)
189+
settings_reader = SettingsReader.from_file(pyproject_toml, config_settings)
190190
settings = settings_reader.settings
191191
assert list(settings_reader.unrecognized_options()) == []
192192

@@ -228,7 +228,7 @@ def test_skbuild_settings_pyproject_toml_broken(tmp_path, capsys):
228228

229229
config_settings: dict[str, list[str] | str] = {}
230230

231-
settings_reader = SettingsReader(pyproject_toml, config_settings)
231+
settings_reader = SettingsReader.from_file(pyproject_toml, config_settings)
232232
assert list(settings_reader.unrecognized_options()) == [
233233
"tool.scikit-build.cmake.minimum-verison",
234234
"tool.scikit-build.logger",
@@ -260,7 +260,7 @@ def test_skbuild_settings_pyproject_conf_broken(tmp_path, capsys):
260260
"logger.level": "INFO",
261261
}
262262

263-
settings_reader = SettingsReader(pyproject_toml, config_settings)
263+
settings_reader = SettingsReader.from_file(pyproject_toml, config_settings)
264264
assert list(settings_reader.unrecognized_options()) == [
265265
"cmake.minimum-verison",
266266
"logger",

0 commit comments

Comments
 (0)