1414
1515""
1616
17- load ("@pythons_hub//:versions.bzl" , "DEFAULT_PYTHON_VERSION" , "MINOR_MAPPING" )
18- load ("@rules_testing//lib:analysis_test.bzl" , "analysis_test" )
19- load ("@rules_testing//lib:test_suite.bzl" , "test_suite" )
20- load ("@rules_testing//lib:util.bzl" , rt_util = "util" )
2117load ("//python:versions.bzl" , "PLATFORMS" , "TOOL_VERSIONS" )
22- load ("//python/private:bzlmod_enabled.bzl" , "BZLMOD_ENABLED" ) # buildifier: disable=bzl-visibility
23- load ("//python/private:full_version.bzl" , "full_version" ) # buildifier: disable=bzl-visibility
24- load ("//python/private:toolchain_types.bzl" , "EXEC_TOOLS_TOOLCHAIN_TYPE" ) # buildifier: disable=bzl-visibility
2518load ("//tests/support:sh_py_run_test.bzl" , "py_reconfig_test" )
26- load ("//tests/support:support.bzl" , "PYTHON_VERSION" )
27-
28- _analysis_tests = []
29-
30- def _transition_impl (input_settings , attr ):
31- settings = {
32- PYTHON_VERSION : input_settings [PYTHON_VERSION ],
33- }
34- if attr .python_version :
35- settings [PYTHON_VERSION ] = attr .python_version
36- return settings
37-
38- _python_version_transition = transition (
39- implementation = _transition_impl ,
40- inputs = [PYTHON_VERSION ],
41- outputs = [PYTHON_VERSION ],
42- )
43-
44- TestInfo = provider (
45- doc = "" ,
46- fields = {
47- "got" : "" ,
48- "want" : "" ,
49- },
50- )
51-
52- def _lock_impl (ctx ):
53- exec_tools = ctx .toolchains [EXEC_TOOLS_TOOLCHAIN_TYPE ].exec_tools
54- got_version = exec_tools .exec_interpreter [platform_common .ToolchainInfo ].py3_runtime .interpreter_version_info
55- return [
56- TestInfo (
57- got = "{}.{}.{}" .format (
58- got_version .major ,
59- got_version .minor ,
60- got_version .micro ,
61- ),
62- want = ctx .attr .want_version ,
63- ),
64- ]
65-
66- _simple_transition = rule (
67- implementation = _lock_impl ,
68- attrs = {
69- "python_version" : attr .string (
70- doc = "Public, see the docs in the macro." ,
71- ),
72- "want_version" : attr .string (
73- doc = "Public, see the docs in the macro." ,
74- ),
75- "_allowlist_function_transition" : attr .label (
76- default = "@bazel_tools//tools/allowlists/function_transition_allowlist" ,
77- ),
78- },
79- toolchains = [
80- EXEC_TOOLS_TOOLCHAIN_TYPE ,
81- ],
82- cfg = _python_version_transition ,
83- )
84-
85- def _test_toolchain_precedence (name ):
86- # First we expect the transitions with a specific version to always
87- # give us that specific version
88- exact_version_tests = {
89- (v , v ): v .replace ("." , "_" )
90- for v in TOOL_VERSIONS
91- }
92-
93- if BZLMOD_ENABLED :
94- # Then we expect to get the version in the MINOR_MAPPING if we provide
95- # the version from the MINOR_MAPPING
96- minor_mapping_tests = {
97- (minor , full ): minor .replace ("." , "_" )
98- for minor , full in MINOR_MAPPING .items ()
99- }
100-
101- # Lastly, if we don't provide any version to the transition, we should
102- # get the default version
103- default_version = full_version (
104- version = DEFAULT_PYTHON_VERSION ,
105- minor_mapping = MINOR_MAPPING ,
106- )
107- default_version_tests = {
108- (None , default_version ): "default" ,
109- }
110- tests = exact_version_tests | minor_mapping_tests | default_version_tests
111- else :
112- # Outside bzlmod the default version and the minor mapping tests do not
113- # make sense because the user loading things in the WORKSPACE ultimately defines
114- # the matching order.
115- tests = exact_version_tests
116-
117- analysis_test (
118- name = name ,
119- impl = _test_toolchain_precedence_impl ,
120- targets = {
121- "{}_{}" .format (name , test_name ): rt_util .helper_target (
122- _simple_transition ,
123- name = "{}_{}" .format (name , test_name ),
124- python_version = input_version ,
125- want_version = want_version ,
126- )
127- for (input_version , want_version ), test_name in tests .items ()
128- },
129- )
130-
131- def _test_toolchain_precedence_impl (env , targets ):
132- # Check that the forwarded PyRuntimeInfo looks vaguely correct.
133- for target in dir (targets ):
134- test_info = env .expect .that_target (target ).provider (
135- TestInfo ,
136- factory = lambda v , meta : v ,
137- )
138- env .expect .that_str (test_info .got ).equals (test_info .want )
139-
140- _analysis_tests .append (_test_toolchain_precedence )
14119
14220def define_toolchain_tests (name ):
14321 """Define the toolchain tests.
14422
14523 Args:
14624 name: Only present to satisfy tooling.
14725 """
148- test_suite (
149- name = name ,
150- tests = _analysis_tests ,
151- )
152-
15326 for platform_key , platform_info in PLATFORMS .items ():
15427 native .config_setting (
15528 name = "_is_{}" .format (platform_key ),
15629 flag_values = platform_info .flag_values ,
15730 constraint_values = platform_info .compatible_with ,
15831 )
15932
160- # First we expect the transitions with a specific version to always
161- # give us that specific version
162- exact_version_tests = {
163- (v , v ): "python_{}_test" .format (v )
164- for v in TOOL_VERSIONS
165- }
166- native .test_suite (
167- name = "exact_version_tests" ,
168- tests = exact_version_tests .values (),
169- )
170-
171- if BZLMOD_ENABLED :
172- # Then we expect to get the version in the MINOR_MAPPING if we provide
173- # the version from the MINOR_MAPPING
174- minor_mapping_tests = {
175- (minor , full ): "python_{}_test" .format (minor )
176- for minor , full in MINOR_MAPPING .items ()
177- }
178- native .test_suite (
179- name = "minor_mapping_tests" ,
180- tests = minor_mapping_tests .values (),
181- )
182-
183- # Lastly, if we don't provide any version to the transition, we should
184- # get the default version
185- default_version = full_version (
186- version = DEFAULT_PYTHON_VERSION ,
187- minor_mapping = MINOR_MAPPING ,
188- )
189- default_version_tests = {
190- (None , default_version ): "default_version_test" ,
191- }
192- tests = exact_version_tests | minor_mapping_tests | default_version_tests
193- else :
194- # Outside bzlmod the default version and the minor mapping tests do not
195- # make sense because the user loading things in the WORKSPACE ultimately defines
196- # the matching order.
197- tests = exact_version_tests
198-
199- for (input_python_version , expect_python_version ), test_name in tests .items ():
200- meta = TOOL_VERSIONS [expect_python_version ]
33+ for python_version , meta in TOOL_VERSIONS .items ():
20134 target_compatible_with = {
20235 "//conditions:default" : ["@platforms//:incompatible" ],
20336 }
@@ -206,12 +39,12 @@ def define_toolchain_tests(name):
20639 target_compatible_with [is_platform ] = []
20740
20841 py_reconfig_test (
209- name = test_name ,
42+ name = "python_{}_test" . format ( python_version ) ,
21043 srcs = ["python_toolchain_test.py" ],
21144 main = "python_toolchain_test.py" ,
212- python_version = input_python_version ,
45+ python_version = python_version ,
21346 env = {
214- "EXPECT_PYTHON_VERSION" : expect_python_version ,
47+ "EXPECT_PYTHON_VERSION" : python_version ,
21548 },
21649 deps = ["//python/runfiles" ],
21750 data = ["//tests/support:current_build_settings" ],
0 commit comments