Skip to content

Commit 9f6796e

Browse files
enhance testability of setuptools integration points
- enable dependency injecting supposed pyporject data - migrate tests to ue the api directly instead of writing
1 parent 5cd6d2b commit 9f6796e

File tree

2 files changed

+87
-95
lines changed

2 files changed

+87
-95
lines changed

src/setuptools_scm/_integration/setuptools.py

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import setuptools
1010

11+
from .pyproject_reading import PyProjectData
1112
from .pyproject_reading import read_pyproject
1213
from .setup_cfg import _dist_name_from_legacy
1314
from .version_inference import get_version_inference_config
@@ -64,6 +65,8 @@ def version_keyword(
6465
dist: setuptools.Distribution,
6566
keyword: str,
6667
value: bool | dict[str, Any] | Callable[[], dict[str, Any]],
68+
*,
69+
_given_pyproject_data: PyProjectData | None = None,
6770
) -> None:
6871
"""apply version infernce when setup(use_scm_version=...) is used
6972
this takes priority over the finalize_options based version
@@ -83,11 +86,16 @@ def version_keyword(
8386
was_set_by_infer = getattr(dist, "_setuptools_scm_version_set_by_infer", False)
8487

8588
# Get pyproject data
86-
try:
87-
pyproject_data = read_pyproject(missing_section_ok=True, missing_file_ok=True)
88-
except (LookupError, ValueError) as e:
89-
log.debug("Configuration issue in pyproject.toml: %s", e)
90-
return
89+
if _given_pyproject_data is not None:
90+
pyproject_data = _given_pyproject_data
91+
else:
92+
try:
93+
pyproject_data = read_pyproject(
94+
missing_section_ok=True, missing_file_ok=True
95+
)
96+
except (LookupError, ValueError) as e:
97+
log.debug("Configuration issue in pyproject.toml: %s", e)
98+
return
9199

92100
result = get_version_inference_config(
93101
dist_name=dist_name,
@@ -100,7 +108,9 @@ def version_keyword(
100108
result.apply(dist)
101109

102110

103-
def infer_version(dist: setuptools.Distribution) -> None:
111+
def infer_version(
112+
dist: setuptools.Distribution, *, _given_pyproject_data: PyProjectData | None = None
113+
) -> None:
104114
"""apply version inference from the finalize_options hook
105115
this is the default for pyproject.toml based projects that don't use the use_scm_version keyword
106116
@@ -112,14 +122,17 @@ def infer_version(dist: setuptools.Distribution) -> None:
112122

113123
dist_name = _dist_name_from_legacy(dist)
114124

115-
try:
116-
pyproject_data = read_pyproject(missing_section_ok=True)
117-
except FileNotFoundError:
118-
log.debug("pyproject.toml not found, skipping infer_version")
119-
return
120-
except (LookupError, ValueError) as e:
121-
log.debug("Configuration issue in pyproject.toml: %s", e)
122-
return
125+
if _given_pyproject_data is not None:
126+
pyproject_data = _given_pyproject_data
127+
else:
128+
try:
129+
pyproject_data = read_pyproject(missing_section_ok=True)
130+
except FileNotFoundError:
131+
log.debug("pyproject.toml not found, skipping infer_version")
132+
return
133+
except (LookupError, ValueError) as e:
134+
log.debug("Configuration issue in pyproject.toml: %s", e)
135+
return
123136

124137
result = get_version_inference_config(
125138
dist_name=dist_name,

testing/test_integration.py

Lines changed: 60 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,33 +1037,28 @@ def test_infer_version_with_build_requires_no_tool_section(
10371037
wd: WorkDir, monkeypatch: pytest.MonkeyPatch
10381038
) -> None:
10391039
"""Test that infer_version works when setuptools-scm is in build_requires but no [tool.setuptools_scm] section"""
1040-
if sys.version_info < (3, 11):
1041-
pytest.importorskip("tomli")
1042-
10431040
# Set up a git repository with a tag
10441041
wd.commit_testfile("test")
10451042
wd("git tag 1.0.0")
10461043
monkeypatch.chdir(wd.cwd)
10471044

1048-
# Create a pyproject.toml file with setuptools_scm in build-system.requires but NO [tool.setuptools_scm] section
1049-
pyproject_content = """
1050-
[build-system]
1051-
requires = ["setuptools>=80", "setuptools_scm>=8"]
1052-
build-backend = "setuptools.build_meta"
1053-
1054-
[project]
1055-
name = "test-package-infer-version"
1056-
dynamic = ["version"]
1057-
"""
1058-
wd.write("pyproject.toml", pyproject_content)
1059-
1045+
from setuptools_scm._integration.pyproject_reading import PyProjectData
10601046
from setuptools_scm._integration.setuptools import infer_version
10611047

1048+
# Create pyproject data: setuptools_scm required, no tool section, project with dynamic=['version']
1049+
pyproject_data = PyProjectData.for_testing(
1050+
is_required=True,
1051+
section_present=False,
1052+
project_present=True,
1053+
project_name="test-package-infer-version",
1054+
has_dynamic_version=True,
1055+
)
1056+
10621057
# Create clean distribution
10631058
dist = create_clean_distribution("test-package-infer-version")
10641059

1065-
# Call infer_version - this should work because setuptools_scm is in build-system.requires
1066-
infer_version(dist)
1060+
# Call infer_version with direct data injection - no file I/O!
1061+
infer_version(dist, _given_pyproject_data=pyproject_data)
10671062

10681063
# Verify that version was set
10691064
assert dist.metadata.version is not None
@@ -1077,33 +1072,28 @@ def test_infer_version_with_build_requires_dash_variant_no_tool_section(
10771072
wd: WorkDir, monkeypatch: pytest.MonkeyPatch
10781073
) -> None:
10791074
"""Test that infer_version works when setuptools-scm (dash variant) is in build_requires but no [tool.setuptools_scm] section"""
1080-
if sys.version_info < (3, 11):
1081-
pytest.importorskip("tomli")
1082-
10831075
# Set up a git repository with a tag
10841076
wd.commit_testfile("test")
10851077
wd("git tag 1.0.0")
10861078
monkeypatch.chdir(wd.cwd)
10871079

1088-
# Create a pyproject.toml file with setuptools-scm (dash variant) in build-system.requires but NO [tool.setuptools_scm] section
1089-
pyproject_content = """
1090-
[build-system]
1091-
requires = ["setuptools>=80", "setuptools-scm>=8"]
1092-
build-backend = "setuptools.build_meta"
1093-
1094-
[project]
1095-
name = "test-package-infer-version-dash"
1096-
dynamic = ["version"]
1097-
"""
1098-
wd.write("pyproject.toml", pyproject_content)
1099-
1080+
from setuptools_scm._integration.pyproject_reading import PyProjectData
11001081
from setuptools_scm._integration.setuptools import infer_version
11011082

1083+
# Create pyproject data: setuptools-scm required, no tool section, project with dynamic=['version']
1084+
pyproject_data = PyProjectData.for_testing(
1085+
is_required=True,
1086+
section_present=False,
1087+
project_present=True,
1088+
project_name="test-package-infer-version-dash",
1089+
has_dynamic_version=True,
1090+
)
1091+
11021092
# Create clean distribution
11031093
dist = create_clean_distribution("test-package-infer-version-dash")
11041094

1105-
# Call infer_version - this should work because setuptools-scm is in build-system.requires
1106-
infer_version(dist)
1095+
# Call infer_version with direct data injection - no file I/O!
1096+
infer_version(dist, _given_pyproject_data=pyproject_data)
11071097

11081098
# Verify that version was set
11091099
assert dist.metadata.version is not None
@@ -1117,32 +1107,28 @@ def test_infer_version_without_build_requires_no_tool_section_silently_returns(
11171107
wd: WorkDir, monkeypatch: pytest.MonkeyPatch
11181108
) -> None:
11191109
"""Test that infer_version silently returns when setuptools-scm is NOT in build_requires and no [tool.setuptools_scm] section"""
1120-
if sys.version_info < (3, 11):
1121-
pytest.importorskip("tomli")
1122-
11231110
# Set up a git repository with a tag
11241111
wd.commit_testfile("test")
11251112
wd("git tag 1.0.0")
11261113
monkeypatch.chdir(wd.cwd)
11271114

1128-
# Create a pyproject.toml file WITHOUT setuptools_scm in build-system.requires and NO [tool.setuptools_scm] section
1129-
pyproject_content = """
1130-
[build-system]
1131-
requires = ["setuptools>=80", "wheel"]
1132-
build-backend = "setuptools.build_meta"
1133-
1134-
[project]
1135-
name = "test-package-no-scm"
1136-
dynamic = ["version"]
1137-
"""
1138-
wd.write("pyproject.toml", pyproject_content)
1139-
1115+
from setuptools_scm._integration.pyproject_reading import PyProjectData
11401116
from setuptools_scm._integration.setuptools import infer_version
11411117

1118+
# Create pyproject data: setuptools-scm NOT required, no tool section, project with dynamic=['version']
1119+
pyproject_data = PyProjectData.for_testing(
1120+
is_required=False, # This is the key: NOT in build-system.requires
1121+
section_present=False,
1122+
project_present=True,
1123+
project_name="test-package-no-scm",
1124+
has_dynamic_version=True,
1125+
)
1126+
11421127
# Create clean distribution
11431128
dist = create_clean_distribution("test-package-no-scm")
11441129

1145-
infer_version(dist)
1130+
# Call infer_version with direct data injection - should silently return
1131+
infer_version(dist, _given_pyproject_data=pyproject_data)
11461132
assert dist.metadata.version is None
11471133

11481134

@@ -1154,27 +1140,25 @@ def test_version_keyword_no_scm_dependency_works(
11541140
wd("git tag 1.0.0")
11551141
monkeypatch.chdir(wd.cwd)
11561142

1157-
# Create a pyproject.toml file WITHOUT setuptools_scm in build-system.requires
1158-
# and WITHOUT [tool.setuptools_scm] section
1159-
pyproject_content = """
1160-
[build-system]
1161-
requires = ["setuptools>=80"]
1162-
build-backend = "setuptools.build_meta"
1163-
1164-
[project]
1165-
name = "test-package-no-scm"
1166-
dynamic = ["version"]
1167-
"""
1168-
wd.write("pyproject.toml", pyproject_content)
1169-
11701143
import setuptools
11711144

1145+
from setuptools_scm._integration.pyproject_reading import PyProjectData
11721146
from setuptools_scm._integration.setuptools import version_keyword
11731147

1148+
# Create pyproject data: setuptools-scm NOT required, no tool section, project with dynamic=['version']
1149+
pyproject_data = PyProjectData.for_testing(
1150+
is_required=False, # This is the key: NOT in build-system.requires
1151+
section_present=False,
1152+
project_present=True,
1153+
project_name="test-package-no-scm",
1154+
has_dynamic_version=True,
1155+
)
1156+
11741157
# Create distribution
11751158
dist = setuptools.Distribution({"name": "test-package-no-scm"})
11761159

1177-
version_keyword(dist, "use_scm_version", True)
1160+
# Call version_keyword with direct data injection - should work regardless of config
1161+
version_keyword(dist, "use_scm_version", True, _given_pyproject_data=pyproject_data)
11781162
assert dist.metadata.version == "1.0.0"
11791163

11801164

@@ -1242,33 +1226,28 @@ def test_infer_version_logs_debug_when_missing_dynamic_version(
12421226
wd: WorkDir, monkeypatch: pytest.MonkeyPatch
12431227
) -> None:
12441228
"""Test that infer_version gracefully handles and logs debug info when setuptools-scm is in build-system.requires but dynamic=['version'] is missing"""
1245-
if sys.version_info < (3, 11):
1246-
pytest.importorskip("tomli")
1247-
12481229
# Set up a git repository with a tag
12491230
wd.commit_testfile("test")
12501231
wd("git tag 1.0.0")
12511232
monkeypatch.chdir(wd.cwd)
12521233

1253-
# Create a pyproject.toml file with setuptools-scm in build-system.requires but NO dynamic=['version']
1254-
pyproject_content = """
1255-
[build-system]
1256-
requires = ["setuptools>=80", "setuptools-scm>=8"]
1257-
build-backend = "setuptools.build_meta"
1258-
1259-
[project]
1260-
name = "test-package-missing-dynamic"
1261-
# Missing: dynamic = ["version"]
1262-
"""
1263-
wd.write("pyproject.toml", pyproject_content)
1264-
1234+
from setuptools_scm._integration.pyproject_reading import PyProjectData
12651235
from setuptools_scm._integration.setuptools import infer_version
12661236

1237+
# Create pyproject data: setuptools-scm required, project present, but no dynamic=['version']
1238+
pyproject_data = PyProjectData.for_testing(
1239+
is_required=True,
1240+
section_present=False,
1241+
project_present=True,
1242+
project_name="test-package-missing-dynamic",
1243+
has_dynamic_version=False, # This is the key: missing dynamic=['version']
1244+
)
1245+
12671246
# Create clean distribution
12681247
dist = create_clean_distribution("test-package-missing-dynamic")
12691248

1270-
# This should not raise an error, but should log debug info about the configuration issue
1271-
infer_version(dist)
1249+
# This should not raise an error, but should silently return (the configuration issue is handled internally)
1250+
infer_version(dist, _given_pyproject_data=pyproject_data)
12721251

12731252
# Verify that version was not set due to configuration issue
12741253
assert dist.metadata.version is None

0 commit comments

Comments
 (0)