Skip to content

Commit 66e16e2

Browse files
Merge pull request #1190 from RonnyPfannschmidt/fix-1184-infer-version-indirect-should-ignore
fix 1184 infer version indirect should ignore
2 parents 3205db5 + 749cc65 commit 66e16e2

File tree

4 files changed

+163
-2
lines changed

4 files changed

+163
-2
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## v9.0.3
4+
5+
### fixed
6+
7+
- fix 1184: verify version is dynamic if the dependency is used as indicator for enabling
8+
39
## v9.0.2
410

511
### Fixed

src/setuptools_scm/_integration/pyproject_reading.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,19 @@ class PyProjectData(NamedTuple):
2828
def project_name(self) -> str | None:
2929
return self.project.get("name")
3030

31+
def verify_dynamic_version_when_required(self) -> None:
32+
"""Verify that dynamic=['version'] is set when setuptools-scm is used as build dependency indicator."""
33+
if self.is_required and not self.section_present:
34+
# When setuptools-scm is in build-system.requires but no tool section exists,
35+
# we need to verify that dynamic=['version'] is set in the project section
36+
dynamic = self.project.get("dynamic", [])
37+
if "version" not in dynamic:
38+
raise ValueError(
39+
f"{self.path}: setuptools-scm is present in [build-system].requires "
40+
f"but dynamic=['version'] is not set in [project]. "
41+
f"Either add dynamic=['version'] to [project] or add a [tool.{self.tool_name}] section."
42+
)
43+
3144

3245
def has_build_package(
3346
requires: Sequence[str], build_package_names: Sequence[str]
@@ -74,10 +87,15 @@ def read_pyproject(
7487
section_present = False
7588

7689
project = defn.get("project", {})
77-
return PyProjectData(
90+
pyproject_data = PyProjectData(
7891
path, tool_name, project, section, is_required, section_present
7992
)
8093

94+
# Verify dynamic version when setuptools-scm is used as build dependency indicator
95+
pyproject_data.verify_dynamic_version_when_required()
96+
97+
return pyproject_data
98+
8199

82100
def get_args_for_pyproject(
83101
pyproject: PyProjectData,

src/setuptools_scm/_integration/setuptools.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,10 @@ def infer_version(dist: setuptools.Distribution) -> None:
160160
return # No setuptools-scm configuration, silently return
161161
except (FileNotFoundError, LookupError):
162162
return # No pyproject.toml or other issues, silently return
163+
except ValueError as e:
164+
# Log the error as debug info instead of raising it
165+
log.debug("Configuration issue in pyproject.toml: %s", e)
166+
return # Configuration issue, silently return
163167

164168
try:
165169
config = _config.Configuration.from_file(

testing/test_integration.py

Lines changed: 134 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ def test_pyproject_missing_setup_hook_works(wd: WorkDir, use_scm_version: str) -
132132
[build-system]
133133
requires=["setuptools", "setuptools_scm"]
134134
build-backend = "setuptools.build_meta"
135-
[tool]
135+
[tool.setuptools_scm]
136136
"""
137137
),
138138
)
@@ -743,6 +743,7 @@ def test_build_requires_integration_with_config_reading(wd: WorkDir) -> None:
743743
744744
[project]
745745
name = "test-package"
746+
dynamic = ["version"]
746747
"""
747748
),
748749
)
@@ -763,6 +764,7 @@ def test_build_requires_integration_with_config_reading(wd: WorkDir) -> None:
763764
764765
[project]
765766
name = "test-package"
767+
dynamic = ["version"]
766768
"""
767769
),
768770
)
@@ -1072,3 +1074,134 @@ def test_version_keyword_no_scm_dependency_works(
10721074

10731075
version_keyword(dist, "use_scm_version", True)
10741076
assert dist.metadata.version == "1.0.0"
1077+
1078+
1079+
def test_verify_dynamic_version_when_required_missing_dynamic(
1080+
wd: WorkDir, monkeypatch: pytest.MonkeyPatch
1081+
) -> None:
1082+
"""Test that verification fails when setuptools-scm is in build-system.requires but dynamic=['version'] is missing"""
1083+
if sys.version_info < (3, 11):
1084+
pytest.importorskip("tomli")
1085+
1086+
# Change to the test directory
1087+
monkeypatch.chdir(wd.cwd)
1088+
1089+
# Create a pyproject.toml file with setuptools-scm in build-system.requires but NO dynamic=['version']
1090+
pyproject_content = """
1091+
[build-system]
1092+
requires = ["setuptools>=80", "setuptools-scm>=8"]
1093+
build-backend = "setuptools.build_meta"
1094+
1095+
[project]
1096+
name = "test-package-missing-dynamic"
1097+
# Missing: dynamic = ["version"]
1098+
"""
1099+
wd.write("pyproject.toml", pyproject_content)
1100+
1101+
from setuptools_scm._integration.pyproject_reading import read_pyproject
1102+
1103+
# This should raise a ValueError because dynamic=['version'] is missing
1104+
with pytest.raises(
1105+
ValueError, match="dynamic=\\['version'\\] is not set in \\[project\\]"
1106+
):
1107+
read_pyproject(Path("pyproject.toml"), missing_section_ok=True)
1108+
1109+
1110+
def test_verify_dynamic_version_when_required_with_tool_section(
1111+
wd: WorkDir, monkeypatch: pytest.MonkeyPatch
1112+
) -> None:
1113+
"""Test that verification passes when setuptools-scm is in build-system.requires and [tool.setuptools_scm] section exists"""
1114+
if sys.version_info < (3, 11):
1115+
pytest.importorskip("tomli")
1116+
1117+
# Change to the test directory
1118+
monkeypatch.chdir(wd.cwd)
1119+
1120+
# Create a pyproject.toml file with setuptools-scm in build-system.requires and [tool.setuptools_scm] section
1121+
pyproject_content = """
1122+
[build-system]
1123+
requires = ["setuptools>=80", "setuptools-scm>=8"]
1124+
build-backend = "setuptools.build_meta"
1125+
1126+
[project]
1127+
name = "test-package-with-tool-section"
1128+
# Missing: dynamic = ["version"]
1129+
1130+
[tool.setuptools_scm]
1131+
"""
1132+
wd.write("pyproject.toml", pyproject_content)
1133+
1134+
from setuptools_scm._integration.pyproject_reading import read_pyproject
1135+
1136+
# This should not raise an error because [tool.setuptools_scm] section exists
1137+
pyproject_data = read_pyproject(Path("pyproject.toml"), missing_section_ok=True)
1138+
assert pyproject_data.is_required is True
1139+
assert pyproject_data.section_present is True
1140+
1141+
1142+
def test_verify_dynamic_version_when_required_with_dynamic(
1143+
wd: WorkDir, monkeypatch: pytest.MonkeyPatch
1144+
) -> None:
1145+
"""Test that verification passes when setuptools-scm is in build-system.requires and dynamic=['version'] is set"""
1146+
if sys.version_info < (3, 11):
1147+
pytest.importorskip("tomli")
1148+
1149+
# Change to the test directory
1150+
monkeypatch.chdir(wd.cwd)
1151+
1152+
# Create a pyproject.toml file with setuptools-scm in build-system.requires and dynamic=['version']
1153+
pyproject_content = """
1154+
[build-system]
1155+
requires = ["setuptools>=80", "setuptools-scm>=8"]
1156+
build-backend = "setuptools.build_meta"
1157+
1158+
[project]
1159+
name = "test-package-with-dynamic"
1160+
dynamic = ["version"]
1161+
"""
1162+
wd.write("pyproject.toml", pyproject_content)
1163+
1164+
from setuptools_scm._integration.pyproject_reading import read_pyproject
1165+
1166+
# This should not raise an error because dynamic=['version'] is set
1167+
pyproject_data = read_pyproject(Path("pyproject.toml"), missing_section_ok=True)
1168+
assert pyproject_data.is_required is True
1169+
assert pyproject_data.section_present is False
1170+
1171+
1172+
def test_infer_version_logs_debug_when_missing_dynamic_version(
1173+
wd: WorkDir, monkeypatch: pytest.MonkeyPatch
1174+
) -> None:
1175+
"""Test that infer_version logs debug info when setuptools-scm is in build-system.requires but dynamic=['version'] is missing"""
1176+
if sys.version_info < (3, 11):
1177+
pytest.importorskip("tomli")
1178+
1179+
# Set up a git repository with a tag
1180+
wd.commit_testfile("test")
1181+
wd("git tag 1.0.0")
1182+
monkeypatch.chdir(wd.cwd)
1183+
1184+
# Create a pyproject.toml file with setuptools-scm in build-system.requires but NO dynamic=['version']
1185+
pyproject_content = """
1186+
[build-system]
1187+
requires = ["setuptools>=80", "setuptools-scm>=8"]
1188+
build-backend = "setuptools.build_meta"
1189+
1190+
[project]
1191+
name = "test-package-missing-dynamic"
1192+
# Missing: dynamic = ["version"]
1193+
"""
1194+
wd.write("pyproject.toml", pyproject_content)
1195+
1196+
import setuptools
1197+
1198+
from setuptools_scm._integration.setuptools import infer_version
1199+
1200+
# Create distribution
1201+
dist = setuptools.Distribution({"name": "test-package-missing-dynamic"})
1202+
1203+
# This should not raise an error, but should log debug info about the configuration issue
1204+
infer_version(dist)
1205+
1206+
# Verify that version was not set due to configuration issue
1207+
assert dist.metadata.version is None

0 commit comments

Comments
 (0)