1212# See the License for the specific language governing permissions and
1313# limitations under the License.
1414
15- ""
15+ """Unit tests for //python/extensions:python.bzl bzlmod extension."""
1616
1717load ("@pythons_hub//:versions.bzl" , "MINOR_MAPPING" )
1818load ("@rules_testing//lib:test_suite.bzl" , "test_suite" )
@@ -43,6 +43,7 @@ def _mock_mctx(*modules, environ = {}, mocked_files = {}):
4343 ],
4444 )
4545
46+ # todo: change is_root to false by default. most modules aren't root
4647def _mod (* , name , defaults = [], toolchain = [], override = [], single_version_override = [], single_version_platform_override = [], is_root = True ):
4748 return struct (
4849 name = name ,
@@ -88,6 +89,15 @@ def _override(
8889 register_all_versions = register_all_versions ,
8990 )
9091
92+ def _rules_python_module (is_root = False ):
93+ """A mock of what the real rules_python MODULE.bazel looks like."""
94+ return _mod (
95+ name = "rules_python" ,
96+ defaults = [_defaults (python_version = "3.11" )],
97+ toolchain = [_toolchain ("3.11" )],
98+ is_root = is_root ,
99+ )
100+
91101def _single_version_override (
92102 python_version = "" ,
93103 sha256 = {},
@@ -138,10 +148,11 @@ def _single_version_platform_override(
138148 arch = "" ,
139149 )
140150
141- def _test_default (env ):
151+ def _test_default_from_rules_python_when_rules_python_is_root (env ):
152+ """Verify that rules_python (as root module) default is applied."""
142153 py = parse_modules (
143154 module_ctx = _mock_mctx (
144- _mod ( name = "rules_python" , toolchain = [ _toolchain ( "3.11" )] ),
155+ _rules_python_module ( is_root = True ),
145156 ),
146157 logger = repo_utils .logger (verbosity_level = 0 , name = "python" ),
147158 )
@@ -167,12 +178,13 @@ def _test_default(env):
167178 )
168179 env .expect .that_collection (py .toolchains ).contains_exactly ([want_toolchain ])
169180
170- _tests .append (_test_default )
181+ _tests .append (_test_default_from_rules_python_when_rules_python_is_root )
171182
172- def _test_default_some_module (env ):
183+ def _test_default_from_rules_python_when_rules_python_is_not_root (env ):
184+ """Verify that rules_python default applies when rules_python is not the root module."""
173185 py = parse_modules (
174186 module_ctx = _mock_mctx (
175- _mod ( name = "rules_python" , toolchain = [ _toolchain ( "3.11" )], is_root = False ),
187+ _rules_python_module ( ),
176188 ),
177189 logger = repo_utils .logger (verbosity_level = 0 , name = "python" ),
178190 )
@@ -186,12 +198,13 @@ def _test_default_some_module(env):
186198 )
187199 env .expect .that_collection (py .toolchains ).contains_exactly ([want_toolchain ])
188200
189- _tests .append (_test_default_some_module )
201+ _tests .append (_test_default_from_rules_python_when_rules_python_is_not_root )
190202
191203def _test_default_with_patch_version (env ):
192204 py = parse_modules (
193205 module_ctx = _mock_mctx (
194- _mod (name = "rules_python" , toolchain = [_toolchain ("3.11.2" )]),
206+ _mod (name = "alpha" , toolchain = [_toolchain ("3.11.2" )]),
207+ _rules_python_module (is_root = True ),
195208 ),
196209 logger = repo_utils .logger (verbosity_level = 0 , name = "python" ),
197210 )
@@ -203,39 +216,18 @@ def _test_default_with_patch_version(env):
203216 python_version = "3.11.2" ,
204217 register_coverage_tool = False ,
205218 )
206- env .expect .that_collection (py .toolchains ).contains_exactly ([want_toolchain ])
219+ env .expect .that_collection (py .toolchains ).contains_at_least ([want_toolchain ])
207220
208221_tests .append (_test_default_with_patch_version )
209222
210- def _test_default_non_rules_python (env ):
211- py = parse_modules (
212- module_ctx = _mock_mctx (
213- # NOTE @aignas 2024-09-06: the first item in the module_ctx.modules
214- # could be a non-root module, which is the case if the root module
215- # does not make any calls to the extension.
216- _mod (name = "rules_python" , toolchain = [_toolchain ("3.11" )], is_root = False ),
217- ),
218- logger = repo_utils .logger (verbosity_level = 0 , name = "python" ),
219- )
220-
221- env .expect .that_str (py .default_python_version ).equals ("3.11" )
222- rules_python_toolchain = struct (
223- name = "python_3_11" ,
224- python_version = "3.11" ,
225- register_coverage_tool = False ,
226- )
227- env .expect .that_collection (py .toolchains ).contains_exactly ([rules_python_toolchain ])
228-
229- _tests .append (_test_default_non_rules_python )
230-
231223def _test_default_non_rules_python_ignore_root_user_error (env ):
232224 py = parse_modules (
233225 module_ctx = _mock_mctx (
234226 _mod (
235227 name = "my_module" ,
236228 toolchain = [_toolchain ("3.12" , ignore_root_user_error = False )],
237229 ),
238- _mod ( name = "rules_python" , toolchain = [ _toolchain ( "3.11" )] ),
230+ _rules_python_module ( ),
239231 ),
240232 logger = repo_utils .logger (verbosity_level = 0 , name = "python" ),
241233 )
@@ -265,7 +257,7 @@ def _test_default_non_rules_python_ignore_root_user_error_non_root_module(env):
265257 module_ctx = _mock_mctx (
266258 _mod (name = "my_module" , toolchain = [_toolchain ("3.13" )]),
267259 _mod (name = "some_module" , toolchain = [_toolchain ("3.12" , ignore_root_user_error = False )]),
268- _mod ( name = "rules_python" , toolchain = [ _toolchain ( "3.11" )] ),
260+ _rules_python_module ( ),
269261 ),
270262 logger = repo_utils .logger (verbosity_level = 0 , name = "python" ),
271263 )
@@ -311,7 +303,7 @@ def _test_toolchain_ordering(env):
311303 _toolchain ("3.11.13" , is_default = True ),
312304 ],
313305 ),
314- _mod ( name = "rules_python" , toolchain = [ _toolchain ( "3.11" )] ),
306+ _rules_python_module ( ),
315307 ),
316308 logger = repo_utils .logger (verbosity_level = 0 , name = "python" ),
317309 )
@@ -433,12 +425,68 @@ def _test_default_from_defaults_file(env):
433425
434426_tests .append (_test_default_from_defaults_file )
435427
428+ def _test_default_from_single_toolchain (env ):
429+ py = parse_modules (
430+ module_ctx = _mock_mctx (
431+ _mod (
432+ name = "my_root_module" ,
433+ toolchain = [_toolchain ("3.12" )],
434+ is_root = True ,
435+ ),
436+ _rules_python_module (),
437+ ),
438+ logger = repo_utils .logger (verbosity_level = 0 , name = "python" ),
439+ )
440+ env .expect .that_str (py .default_python_version ).equals ("3.12" )
441+
442+ _tests .append (_test_default_from_single_toolchain )
443+
444+ def _test_defaults_overrides_single_toolchain (env ):
445+ py = parse_modules (
446+ module_ctx = _mock_mctx (
447+ _mod (
448+ name = "my_root_module" ,
449+ defaults = [
450+ # This relies on rules_python registering 3.11
451+ _defaults (python_version = "3.11" ),
452+ ],
453+ toolchain = [_toolchain ("3.12" )],
454+ is_root = True ,
455+ ),
456+ _rules_python_module (),
457+ ),
458+ logger = repo_utils .logger (verbosity_level = 0 , name = "python" ),
459+ )
460+ env .expect .that_str (py .default_python_version ).equals ("3.11" )
461+
462+ _tests .append (_test_defaults_overrides_single_toolchain )
463+
464+ def _test_defaults_overrides_toolchains_setting_is_default (env ):
465+ py = parse_modules (
466+ module_ctx = _mock_mctx (
467+ _mod (
468+ name = "my_root_module" ,
469+ defaults = [_defaults (python_version = "3.13" )],
470+ toolchain = [
471+ _toolchain ("3.13" ),
472+ _toolchain ("3.12" , is_default = True ),
473+ ],
474+ is_root = True ,
475+ ),
476+ _rules_python_module (),
477+ ),
478+ logger = repo_utils .logger (verbosity_level = 0 , name = "python" ),
479+ )
480+ env .expect .that_str (py .default_python_version ).equals ("3.13" )
481+
482+ _tests .append (_test_defaults_overrides_toolchains_setting_is_default )
483+
436484def _test_first_occurance_of_the_toolchain_wins (env ):
437485 py = parse_modules (
438486 module_ctx = _mock_mctx (
439487 _mod (name = "my_module" , toolchain = [_toolchain ("3.12" )]),
440488 _mod (name = "some_module" , toolchain = [_toolchain ("3.12" , configure_coverage_tool = True )]),
441- _mod ( name = "rules_python" , toolchain = [ _toolchain ( "3.11" )] ),
489+ _rules_python_module ( ),
442490 environ = {
443491 "RULES_PYTHON_BZLMOD_DEBUG" : "1" ,
444492 },
@@ -487,7 +535,7 @@ def _test_auth_overrides(env):
487535 ),
488536 ],
489537 ),
490- _mod ( name = "rules_python" , toolchain = [ _toolchain ( "3.11" )] ),
538+ _rules_python_module ( ),
491539 ),
492540 logger = repo_utils .logger (verbosity_level = 0 , name = "python" ),
493541 )
@@ -828,10 +876,12 @@ _tests.append(_test_single_version_platform_override_errors)
828876# * incorrect platform failure
829877# * missing python_version failure
830878
879+ xtests = []
880+
831881def python_test_suite (name ):
832882 """Create the test suite.
833883
834884 Args:
835885 name: the name of the test suite
836886 """
837- test_suite (name = name , basic_tests = _tests )
887+ test_suite (name = name , basic_tests = xtests or _tests )
0 commit comments