33from types import SimpleNamespace
44from typing import Any
55
6+ import pytest
7+
68from setuptools_scm ._integration .pyproject_reading import PyProjectData
79from setuptools_scm ._integration .version_inference import VersionInferenceConfig
810from setuptools_scm ._integration .version_inference import VersionInferenceNoOp
1113from setuptools_scm ._integration .version_inference import get_version_inference_config
1214
1315# Common test data
14- DEFAULT_PYPROJECT_DATA = PyProjectData .for_testing (
15- is_required = True , section_present = True , project_present = True
16- )
17-
18- PYPROJECT_WITHOUT_TOOL_SECTION = PyProjectData .for_testing (
19- is_required = True , section_present = False , project_present = True
20- )
21-
22- PYPROJECT_ONLY_REQUIRED = PyProjectData .for_testing (
23- is_required = True , section_present = False , project_present = False
16+ PYPROJECT = SimpleNamespace (
17+ DEFAULT = PyProjectData .for_testing (
18+ is_required = True , section_present = True , project_present = True
19+ ),
20+ WITHOUT_TOOL_SECTION = PyProjectData .for_testing (
21+ is_required = True , section_present = False , project_present = True
22+ ),
23+ ONLY_REQUIRED = PyProjectData .for_testing (
24+ is_required = True , section_present = False , project_present = False
25+ ),
26+ WITHOUT_PROJECT = PyProjectData .for_testing (
27+ is_required = True , section_present = True , project_present = False
28+ ),
2429)
2530
2631OVERRIDES = SimpleNamespace (
32+ NOT_GIVEN = None ,
2733 EMPTY = {},
2834 CALVER = {"version_scheme" : "calver" },
2935 UNRELATED = {"key" : "value" },
30- INFER_VERSION = None ,
3136)
3237
3338
@@ -45,7 +50,7 @@ def expect_config(
4550 * ,
4651 dist_name : str | None = "test_package" ,
4752 current_version : str | None ,
48- pyproject_data : PyProjectData = DEFAULT_PYPROJECT_DATA ,
53+ pyproject_data : PyProjectData = PYPROJECT . DEFAULT ,
4954 overrides : dict [str , Any ] | None = None ,
5055 expected : type [VersionInferenceConfig ]
5156 | VersionInferenceWarning
@@ -74,63 +79,144 @@ def expect_config(
7479 assert result == expectation
7580
7681
77- class TestVersionInferenceDecision :
78- """Test the version inference decision logic."""
82+ infer_implied = pytest .mark .parametrize (
83+ ("overrides" , "pyproject_data" ),
84+ [
85+ pytest .param (
86+ OVERRIDES .EMPTY , PYPROJECT .DEFAULT , id = "empty_overrides_default_pyproject"
87+ ),
88+ pytest .param (
89+ OVERRIDES .EMPTY ,
90+ PYPROJECT .WITHOUT_TOOL_SECTION ,
91+ id = "empty_overrides_without_tool_section" ,
92+ ),
93+ pytest .param (
94+ OVERRIDES .NOT_GIVEN ,
95+ PYPROJECT .DEFAULT ,
96+ id = "infer_version_default_pyproject" ,
97+ ),
98+ ],
99+ )
79100
80- def test_missing_version_with_overrides_triggers (self ) -> None :
81- """Test that version_keyword context with overrides infers when no existing version."""
82- expect_config (
83- current_version = None , # version_keyword passes None when version was set by infer
84- overrides = OVERRIDES .UNRELATED ,
85- expected = VersionInferenceConfig ,
86- )
87101
88- def test_overrides_on_existing_version_warns (self ) -> None :
89- """note: version_keyword opts out of inference if
90- version is set by something else or overrides are empty"""
91- expect_config (
92- current_version = "1.0.0" , # version set by something else (setup.cfg, etc.)
93- overrides = OVERRIDES .UNRELATED ,
94- expected = WARNING_PACKAGE ,
95- )
102+ @pytest .mark .parametrize ("package_name" , ["test_package" , None ])
103+ @infer_implied
104+ def test_implied_with_version_warns (
105+ package_name : str | None ,
106+ overrides : dict [str , Any ] | None ,
107+ pyproject_data : PyProjectData ,
108+ ) -> None :
109+ expect_config (
110+ dist_name = package_name ,
111+ current_version = "1.0.0" ,
112+ pyproject_data = pyproject_data ,
113+ overrides = overrides ,
114+ expected = WARNING_PACKAGE if package_name else WARNING_NO_PACKAGE ,
115+ )
96116
97- def test_version_already_set_no_overrides (self ) -> None :
98- """infer_version call with existing version warns when inference is implied."""
99- expect_config (
100- current_version = "1.0.0" ,
101- overrides = None ,
102- expected = WARNING_PACKAGE ,
103- )
104117
105- def test_version_keyword_with_empty_overrides (self ) -> None :
106- """Test that version_keyword context with empty overrides infers when no existing version."""
107- expect_config (
108- current_version = None , # version_keyword handles early exit, so this is what we see
109- overrides = OVERRIDES .EMPTY ,
110- expected = VersionInferenceConfig ,
111- )
118+ @pytest .mark .parametrize ("package_name" , ["test_package" , None ])
119+ @infer_implied
120+ def test_implied_without_version_infers (
121+ package_name : str | None ,
122+ overrides : dict [str , Any ] | None ,
123+ pyproject_data : PyProjectData ,
124+ ) -> None :
125+ expect_config (
126+ dist_name = package_name ,
127+ current_version = None ,
128+ pyproject_data = pyproject_data ,
129+ overrides = overrides ,
130+ expected = VersionInferenceConfig ,
131+ )
112132
113- def test_version_keyword_empty_overrides_existing_version (self ) -> None :
114- """Test that version_keyword context with empty overrides and existing version errors."""
115- expect_config (
116- current_version = "1.0.0" , # version set by something else (setup.cfg, etc.)
117- overrides = OVERRIDES .EMPTY ,
118- expected = WARNING_PACKAGE ,
119- )
120133
121- def test_version_already_set_by_something_else (self ) -> None :
122- """infer_version call with existing version warns when inference is implied."""
123- expect_config (
124- current_version = "1.0.0" ,
125- overrides = None ,
126- expected = WARNING_PACKAGE ,
127- )
134+ def test_no_config_no_infer () -> None :
135+ expect_config (
136+ current_version = None ,
137+ pyproject_data = PYPROJECT .WITHOUT_TOOL_SECTION ,
138+ overrides = OVERRIDES .NOT_GIVEN ,
139+ expected = NOOP ,
140+ )
141+
142+
143+ Expectation = SimpleNamespace
144+
145+
146+ class TestVersionInferenceDecision :
147+ """Test the version inference decision logic."""
148+
149+ @pytest .mark .parametrize (
150+ "expectation" ,
151+ [
152+ pytest .param (
153+ Expectation (
154+ current_version = None ,
155+ overrides = OVERRIDES .UNRELATED ,
156+ expected = VersionInferenceConfig ,
157+ ),
158+ id = "missing_version_with_overrides_triggers" ,
159+ ),
160+ pytest .param (
161+ Expectation (
162+ current_version = "1.0.0" ,
163+ overrides = OVERRIDES .UNRELATED ,
164+ expected = WARNING_PACKAGE ,
165+ ),
166+ id = "overrides_on_existing_version_warns" ,
167+ ),
168+ pytest .param (
169+ Expectation (
170+ current_version = "1.0.0" ,
171+ overrides = None ,
172+ expected = WARNING_PACKAGE ,
173+ ),
174+ id = "version_already_set_no_overrides" ,
175+ ),
176+ pytest .param (
177+ Expectation (
178+ current_version = None ,
179+ overrides = OVERRIDES .EMPTY ,
180+ expected = VersionInferenceConfig ,
181+ ),
182+ id = "version_keyword_with_empty_overrides" ,
183+ ),
184+ pytest .param (
185+ Expectation (
186+ current_version = "1.0.0" ,
187+ overrides = OVERRIDES .EMPTY ,
188+ expected = WARNING_PACKAGE ,
189+ ),
190+ id = "version_keyword_empty_overrides_existing_version" ,
191+ ),
192+ pytest .param (
193+ Expectation (
194+ current_version = "1.0.0" ,
195+ overrides = None ,
196+ expected = WARNING_PACKAGE ,
197+ ),
198+ id = "version_already_set_by_something_else" ,
199+ ),
200+ pytest .param (
201+ Expectation (
202+ current_version = None ,
203+ overrides = None ,
204+ expected = VersionInferenceConfig ,
205+ ),
206+ id = "both_required_and_tool_section" ,
207+ ),
208+ ],
209+ )
210+ @pytest .mark .xfail (reason = "TODO: fix this" )
211+ def test_default_package_scenarios (self , expectation : Expectation ) -> None :
212+ """Test version inference scenarios using default package name and pyproject data."""
213+ expectation .check ()
128214
129215 def test_no_setuptools_scm_config_infer_version (self ) -> None :
130216 """Test that we don't infer when setuptools-scm is not configured and infer_version called."""
131217 expect_config (
132218 current_version = None ,
133- pyproject_data = PYPROJECT_WITHOUT_TOOL_SECTION ,
219+ pyproject_data = PYPROJECT . WITHOUT_TOOL_SECTION ,
134220 overrides = None ,
135221 expected = NOOP ,
136222 )
@@ -139,7 +225,7 @@ def test_no_setuptools_scm_config_version_keyword(self) -> None:
139225 """We infer when setuptools-scm is not configured but use_scm_version=True."""
140226 expect_config (
141227 current_version = None ,
142- pyproject_data = PYPROJECT_WITHOUT_TOOL_SECTION ,
228+ pyproject_data = PYPROJECT . WITHOUT_TOOL_SECTION ,
143229 overrides = OVERRIDES .EMPTY ,
144230 expected = VersionInferenceConfig ,
145231 )
@@ -148,7 +234,7 @@ def test_setuptools_scm_required_no_project_section_infer_version(self) -> None:
148234 """We don't infer without tool section even if required: infer_version path."""
149235 expect_config (
150236 current_version = None ,
151- pyproject_data = PYPROJECT_ONLY_REQUIRED ,
237+ pyproject_data = PYPROJECT . ONLY_REQUIRED ,
152238 overrides = None ,
153239 expected = NOOP ,
154240 )
@@ -157,7 +243,7 @@ def test_setuptools_scm_required_no_project_section_version_keyword(self) -> Non
157243 """Test that we DO infer when setuptools-scm is required but no project section and use_scm_version=True."""
158244 expect_config (
159245 current_version = None ,
160- pyproject_data = PYPROJECT_ONLY_REQUIRED ,
246+ pyproject_data = PYPROJECT . ONLY_REQUIRED ,
161247 overrides = OVERRIDES .EMPTY ,
162248 expected = VersionInferenceConfig ,
163249 )
@@ -168,7 +254,7 @@ def test_setuptools_scm_required_no_project_section_version_keyword_with_config(
168254 """Test that we DO infer when setuptools-scm is required but no project section and use_scm_version={config}."""
169255 expect_config (
170256 current_version = None ,
171- pyproject_data = PYPROJECT_ONLY_REQUIRED ,
257+ pyproject_data = PYPROJECT . ONLY_REQUIRED ,
172258 overrides = OVERRIDES .CALVER ,
173259 expected = VersionInferenceConfig ,
174260 )
@@ -177,24 +263,15 @@ def test_setuptools_scm_required_with_project_section(self) -> None:
177263 """We only infer when tool section present, regardless of required/project presence."""
178264 expect_config (
179265 current_version = None ,
180- pyproject_data = PYPROJECT_WITHOUT_TOOL_SECTION ,
266+ pyproject_data = PYPROJECT . WITHOUT_TOOL_SECTION ,
181267 expected = NOOP ,
182268 )
183269
184270 def test_tool_section_present (self ) -> None :
185271 """We infer when tool section is present."""
186272 expect_config (
187273 current_version = None ,
188- pyproject_data = PyProjectData .for_testing (
189- is_required = False , section_present = True , project_present = False
190- ),
191- expected = VersionInferenceConfig ,
192- )
193-
194- def test_both_required_and_tool_section (self ) -> None :
195- """Test that we infer when both required and tool section are present."""
196- expect_config (
197- current_version = None ,
274+ pyproject_data = PYPROJECT .WITHOUT_PROJECT ,
198275 expected = VersionInferenceConfig ,
199276 )
200277
0 commit comments