Skip to content

Commit 096a3e2

Browse files
committed
refactor: simplify hub repo toolchain creation
1 parent c383c3b commit 096a3e2

File tree

9 files changed

+306
-173
lines changed

9 files changed

+306
-173
lines changed

examples/bzlmod/MODULE.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ python.single_version_override(
8989
python.single_version_platform_override(
9090
patch_strip = 1,
9191
patches = [],
92-
platform = "aarch64-apple-darwin",
92+
platform = "aarch64-apple-darwinX",
9393
python_version = "3.10.2",
9494
sha256 = "1409acd9a506e2d1d3b65c1488db4e40d8f19d09a7df099667c87a506f71c0ef",
9595
urls = ["20220227/cpython-{python_version}+20220227-{platform}-{build}.tar.gz"],

internal_dev_setup.bzl

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,15 @@ def rules_python_internal_setup():
3434
name = "pythons_hub",
3535
minor_mapping = MINOR_MAPPING,
3636
default_python_version = "",
37-
toolchain_prefixes = [],
38-
toolchain_python_versions = [],
39-
toolchain_set_python_version_constraints = [],
40-
toolchain_user_repository_names = [],
4137
python_versions = sorted(TOOL_VERSIONS.keys()),
38+
toolchain_names = [],
39+
toolchain_repo_names = {},
40+
toolchain_target_compatible_with_map = {},
41+
toolchain_target_settings_map = {},
42+
toolchain_platform_keys = {},
43+
toolchain_python_versions = {},
44+
toolchain_set_python_version_constraints = {},
45+
base_toolchain_repo_names = [],
4246
)
4347

4448
runtime_env_repo(name = "rules_python_runtime_env_tc_info")

python/private/config_settings.bzl

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ If the value is missing, then the default value is being used, see documentation
3131
{docs_url}/python/config_settings
3232
"""
3333

34+
# Indicates something needs public visibility so that other generated code can
35+
# access it, but it's not intended for general public usage.
36+
_NOT_ACTUALLY_PUBLIC = ["//visibility:public"]
37+
3438
def construct_config_settings(*, name, default_version, versions, minor_mapping, documented_flags): # buildifier: disable=function-docstring
3539
"""Create a 'python_version' config flag and construct all config settings used in rules_python.
3640
@@ -128,7 +132,30 @@ def construct_config_settings(*, name, default_version, versions, minor_mapping,
128132
# `whl_library` in the hub repo created by `pip.parse`.
129133
flag_values = {"current_config": "will-never-match"},
130134
# Only public so that PyPI hub repo can access it
131-
visibility = ["//visibility:public"],
135+
visibility = _NOT_ACTUALLY_PUBLIC,
136+
)
137+
138+
libc = Label("//python/config_settings:py_linux_libc")
139+
native.config_setting(
140+
name = "_is_libc_glibc",
141+
flag_values = {libc: "glibc"},
142+
visibility = _NOT_ACTUALLY_PUBLIC,
143+
)
144+
native.config_setting(
145+
name = "_is_libc_musl",
146+
flag_values = {libc: "glibc"},
147+
visibility = _NOT_ACTUALLY_PUBLIC,
148+
)
149+
freethreaded = Label("//python/config_settings:py_freethreaded")
150+
native.config_setting(
151+
name = "_is_freethreaded_yes",
152+
flag_values = {freethreaded: "yes"},
153+
visibility = _NOT_ACTUALLY_PUBLIC,
154+
)
155+
native.config_setting(
156+
name = "_is_freethreaded_no",
157+
flag_values = {freethreaded: "no"},
158+
visibility = _NOT_ACTUALLY_PUBLIC,
132159
)
133160

134161
def _python_version_flag_impl(ctx):

python/private/py_repositories.bzl

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,15 @@ def py_repositories():
3939
name = "pythons_hub",
4040
minor_mapping = MINOR_MAPPING,
4141
default_python_version = "",
42-
toolchain_prefixes = [],
43-
toolchain_python_versions = [],
44-
toolchain_set_python_version_constraints = [],
45-
toolchain_user_repository_names = [],
4642
python_versions = sorted(TOOL_VERSIONS.keys()),
43+
toolchain_names = [],
44+
toolchain_repo_names = {},
45+
toolchain_target_compatible_with_map = {},
46+
toolchain_target_settings_map = {},
47+
toolchain_platform_keys = {},
48+
toolchain_python_versions = {},
49+
toolchain_set_python_version_constraints = {},
50+
base_toolchain_repo_names = [],
4751
)
4852
http_archive(
4953
name = "bazel_skylib",

python/private/py_toolchain_suite.bzl

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,20 @@ def py_toolchain_suite(
3434
python_version,
3535
set_python_version_constraint,
3636
flag_values,
37+
target_settings = [],
3738
target_compatible_with = []):
3839
"""For internal use only.
3940
4041
Args:
4142
prefix: Prefix for toolchain target names.
42-
user_repository_name: The name of the user repository.
43+
user_repository_name: The name of the repository with the toolchain
44+
implementation (it's assumed to have particular target names within
45+
it). Does not include the leading "@".
4346
python_version: The full (X.Y.Z) version of the interpreter.
4447
set_python_version_constraint: True or False as a string.
45-
flag_values: Extra flag values to match for this toolchain.
48+
flag_values: Extra flag values to match for this toolchain. These
49+
are prepended to target_settings.
50+
target_settings: Extra target_settings to match for this toolchain.
4651
target_compatible_with: list constraints the toolchains are compatible with.
4752
"""
4853

@@ -82,7 +87,7 @@ def py_toolchain_suite(
8287
match_any = match_any,
8388
visibility = ["//visibility:private"],
8489
)
85-
target_settings = [name]
90+
target_settings = [name] + target_settings
8691
else:
8792
fail(("Invalid set_python_version_constraint value: got {} {}, wanted " +
8893
"either the string 'True' or the string 'False'; " +

python/private/python.bzl

Lines changed: 74 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,9 @@ load(":python_register_toolchains.bzl", "python_register_toolchains")
2222
load(":pythons_hub.bzl", "hub_repo")
2323
load(":repo_utils.bzl", "repo_utils")
2424
load(":semver.bzl", "semver")
25-
load(":text_util.bzl", "render")
2625
load(":toolchains_repo.bzl", "multi_toolchain_aliases")
2726
load(":util.bzl", "IS_BAZEL_6_4_OR_HIGHER")
2827

29-
# This limit can be increased essentially arbitrarily, but doing so will cause a rebuild of all
30-
# targets using any of these toolchains due to the changed repository name.
31-
_MAX_NUM_TOOLCHAINS = 9999
32-
_TOOLCHAIN_INDEX_PAD_LENGTH = len(str(_MAX_NUM_TOOLCHAINS))
33-
3428
def parse_modules(*, module_ctx, _fail = fail):
3529
"""Parse the modules and return a struct for registrations.
3630
@@ -240,9 +234,6 @@ def parse_modules(*, module_ctx, _fail = fail):
240234
# toolchain. We need the default last.
241235
toolchains.append(default_toolchain)
242236

243-
if len(toolchains) > _MAX_NUM_TOOLCHAINS:
244-
fail("more than {} python versions are not supported".format(_MAX_NUM_TOOLCHAINS))
245-
246237
# sort the toolchains so that the toolchain versions that are in the
247238
# `minor_mapping` are coming first. This ensures that `python_version =
248239
# "3.X"` transitions work as expected.
@@ -275,6 +266,9 @@ def parse_modules(*, module_ctx, _fail = fail):
275266
def _python_impl(module_ctx):
276267
py = parse_modules(module_ctx = module_ctx)
277268

269+
# dict[str version, list[str] platforms]; where version is full
270+
# python version string ("3.4.5"), and platforms are keys from
271+
# the PLATFORMS global.
278272
loaded_platforms = {}
279273
for toolchain_info in py.toolchains:
280274
# Ensure that we pass the full version here.
@@ -297,30 +291,82 @@ def _python_impl(module_ctx):
297291
**kwargs
298292
)
299293

300-
# Create the pythons_hub repo for the interpreter meta data and the
301-
# the various toolchains.
294+
# List of the base names ("python_3_10") for the toolchain repos
295+
base_toolchain_repo_names = []
296+
297+
# list[str] The infix to use for the resulting toolchain() `name` arg.
298+
toolchain_names = []
299+
300+
# dict[str i, str repo]; where repo is the full repo name
301+
# ("python_3_10_unknown-linux-x86_64") for the toolchain
302+
# i corresponds to index `i` in toolchain_names
303+
toolchain_repo_names = {}
304+
305+
# dict[str i, list[str] constraints]; where constraints is a list
306+
# of labels for target_compatible_with
307+
# i corresponds to index `i` in toolchain_names
308+
toolchain_tcw_map = {}
309+
310+
# dict[str i, list[str] settings]; where settings is a list
311+
# of labels for target_settings
312+
# i corresponds to index `i` in toolchain_names
313+
toolchain_ts_map = {}
314+
315+
# dict[str i, str set_constraint]; where set_constraint is the string
316+
# "True" or "False".
317+
# i corresponds to index `i` in toolchain_names
318+
toolchain_set_python_version_constraints = {}
319+
320+
# dict[str i, str python_version]; where python_version is the full
321+
# python version ("3.4.5").
322+
toolchain_python_versions = {}
323+
324+
# dict[str i, str platform_key]; where platform_key is the key within
325+
# the PLATFORMS global for this toolchain
326+
toolchain_platform_keys = {}
327+
328+
# Split the toolchain info into separate objects so they can be passed onto
329+
# the repository rule.
330+
for i, t in enumerate(py.toolchains):
331+
is_last = (i + 1) == len(py.toolchains)
332+
base_name = t.name
333+
base_toolchain_repo_names.append(base_name)
334+
fv = full_version(version = t.python_version, minor_mapping = py.config.minor_mapping)
335+
for platform in loaded_platforms[fv]:
336+
if platform not in PLATFORMS:
337+
continue
338+
key = str(len(toolchain_names))
339+
340+
full_name = "{}_{}".format(base_name, platform)
341+
toolchain_names.append(full_name)
342+
toolchain_repo_names[key] = full_name
343+
toolchain_tcw_map[key] = PLATFORMS[platform].compatible_with
344+
345+
# The target_settings attribute may not be present for users
346+
# patching python/versions.bzl.
347+
toolchain_ts_map[key] = getattr(PLATFORMS[platform], "target_settings", [])
348+
toolchain_platform_keys[key] = platform
349+
toolchain_python_versions[key] = fv
350+
351+
# The last toolchain is the default; it can't have version constraints
352+
# Despite the implication of the arg name, the values are strs, not bools
353+
toolchain_set_python_version_constraints[key] = (
354+
"True" if not is_last else "False"
355+
)
356+
302357
hub_repo(
303358
name = "pythons_hub",
304-
# Last toolchain is default
359+
toolchain_names = toolchain_names,
360+
toolchain_repo_names = toolchain_repo_names,
361+
toolchain_target_compatible_with_map = toolchain_tcw_map,
362+
toolchain_target_settings_map = toolchain_ts_map,
363+
toolchain_platform_keys = toolchain_platform_keys,
364+
toolchain_python_versions = toolchain_python_versions,
365+
toolchain_set_python_version_constraints = toolchain_set_python_version_constraints,
366+
base_toolchain_repo_names = [t.name for t in py.toolchains],
305367
default_python_version = py.default_python_version,
306368
minor_mapping = py.config.minor_mapping,
307369
python_versions = list(py.config.default["tool_versions"].keys()),
308-
toolchain_prefixes = [
309-
render.toolchain_prefix(index, toolchain.name, _TOOLCHAIN_INDEX_PAD_LENGTH)
310-
for index, toolchain in enumerate(py.toolchains)
311-
],
312-
toolchain_python_versions = [
313-
full_version(version = t.python_version, minor_mapping = py.config.minor_mapping)
314-
for t in py.toolchains
315-
],
316-
# The last toolchain is the default; it can't have version constraints
317-
# Despite the implication of the arg name, the values are strs, not bools
318-
toolchain_set_python_version_constraints = [
319-
"True" if i != len(py.toolchains) - 1 else "False"
320-
for i in range(len(py.toolchains))
321-
],
322-
toolchain_user_repository_names = [t.name for t in py.toolchains],
323-
loaded_platforms = loaded_platforms,
324370
)
325371

326372
# This is require in order to support multiple version py_test

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy