16
16
"""
17
17
18
18
load ("@bazel_skylib//lib:selects.bzl" , "selects" )
19
+ load ("@bazel_skylib//rules:common_settings.bzl" , "string_flag" )
19
20
load ("//python:versions.bzl" , "MINOR_MAPPING" , "TOOL_VERSIONS" )
20
21
21
22
_PYTHON_VERSION_FLAG = str (Label ("//python/config_settings:python_version" ))
@@ -36,8 +37,9 @@ def _flag_values(python_versions):
36
37
python_versions: list of strings; all X.Y.Z python versions
37
38
38
39
Returns:
39
- A map with config settings as keys and values are all of the python_version flag
40
- values that that match the given 'key' specification. For example:
40
+ A `map[str, list[str]]`. Each key is a python_version flag value. Each value
41
+ is a list of the python_version flag values that should match when for the
42
+ `key`. For example:
41
43
```
42
44
"3.8" -> ["3.8", "3.8.1", "3.8.2", ..., "3.8.19"] # All 3.8 versions
43
45
"3.8.2" -> ["3.8.2"] # Only 3.8.2
@@ -67,7 +69,7 @@ def _flag_values(python_versions):
67
69
68
70
VERSION_FLAG_VALUES = _flag_values (TOOL_VERSIONS .keys ())
69
71
70
- def is_python_config_setting (name , * , python_version = None , match_any = None , ** kwargs ):
72
+ def is_python_config_setting (name , * , python_version , match_any = None , ** kwargs ):
71
73
"""Create a config setting for matching 'python_version' configuration flag.
72
74
73
75
This function is mainly intended for internal use within the `whl_library` and `pip_parse`
@@ -81,19 +83,19 @@ def is_python_config_setting(name, *, python_version = None, match_any = None, *
81
83
either None, which will create config settings necessary to match the `python_version` value,
82
84
a list of 'config_setting' labels passed to bazel-skylib's `config_setting_group` `match_any`
83
85
attribute.
84
- **kwargs: extra kwargs passed to the `config_setting`
86
+ **kwargs: extra kwargs passed to the `config_setting`.
85
87
"""
86
- visibility = kwargs .pop ("visibility" , [])
87
-
88
- flag_values = {
89
- _PYTHON_VERSION_FLAG : python_version ,
90
- }
91
88
if python_version not in name :
92
89
fail ("The name '{}' must have the python version '{}' in it" .format (name , python_version ))
93
90
94
91
if python_version not in VERSION_FLAG_VALUES :
95
92
fail ("The 'python_version' must be known to 'rules_python', choose from the values: {}" .format (VERSION_FLAG_VALUES .keys ()))
96
93
94
+ flag_values = {
95
+ _PYTHON_VERSION_FLAG : python_version ,
96
+ }
97
+ visibility = kwargs .pop ("visibility" , [])
98
+
97
99
python_versions = VERSION_FLAG_VALUES [python_version ]
98
100
if len (python_versions ) == 1 and not match_any :
99
101
native .config_setting (
@@ -141,3 +143,41 @@ def is_python_config_setting(name, *, python_version = None, match_any = None, *
141
143
actual = "_{}_group" .format (name ),
142
144
visibility = visibility ,
143
145
)
146
+
147
+ def construct_config_settings (name = None ): # buildifier: disable=function-docstring
148
+ """Create a 'python_version' config flag and construct all config settings used in rules_python.
149
+
150
+ This mainly includes the targets that are used in the toolchain and pip hub
151
+ repositories that only match on the 'python_version' flag values.
152
+
153
+ Args:
154
+ name(str): A dummy name value that is no-op for now.
155
+ """
156
+ string_flag (
157
+ name = "python_version" ,
158
+ # TODO: The default here should somehow match the MODULE config. Until
159
+ # then, use the empty string to indicate an unknown version. This
160
+ # also prevents version-unaware targets from inadvertently matching
161
+ # a select condition when they shouldn't.
162
+ build_setting_default = "" ,
163
+ values = ["" ] + VERSION_FLAG_VALUES .keys (),
164
+ visibility = ["//visibility:public" ],
165
+ )
166
+
167
+ for version , matching_versions in VERSION_FLAG_VALUES .items ():
168
+ match_any = None
169
+ if len (matching_versions ) > 1 :
170
+ match_any = [
171
+ # Use the internal labels created by this macro in order to handle matching
172
+ # 3.8 config value if using the 3.8 version from MINOR_MAPPING with generating
173
+ # fewer targets overall.
174
+ ("_is_python_{}" if len (VERSION_FLAG_VALUES [v ]) > 1 else "is_python_{}" ).format (v )
175
+ for v in matching_versions
176
+ ]
177
+
178
+ is_python_config_setting (
179
+ name = "is_python_{}" .format (version ),
180
+ python_version = version ,
181
+ match_any = match_any ,
182
+ visibility = ["//visibility:public" ],
183
+ )
0 commit comments