Skip to content

Commit 6dbdef9

Browse files
committed
refactor: explicitly define host platform ordering selection
1 parent 2d4fd4a commit 6dbdef9

File tree

3 files changed

+59
-12
lines changed

3 files changed

+59
-12
lines changed

python/private/python.bzl

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ load(":full_version.bzl", "full_version")
2121
load(":python_register_toolchains.bzl", "python_register_toolchains")
2222
load(":pythons_hub.bzl", "hub_repo")
2323
load(":repo_utils.bzl", "repo_utils")
24-
load(":toolchains_repo.bzl", "host_toolchain", "multi_toolchain_aliases")
24+
load(":toolchains_repo.bzl", "host_toolchain", "multi_toolchain_aliases", "sorted_host_platforms")
2525
load(":util.bzl", "IS_BAZEL_6_4_OR_HIGHER")
2626
load(":version.bzl", "version")
2727

@@ -298,9 +298,8 @@ def _python_impl(module_ctx):
298298
_internal_bzlmod_toolchain_call = True,
299299
**kwargs
300300
)
301-
host_platforms = []
302-
host_os_names = {}
303-
host_archs = {}
301+
302+
host_platforms = {}
304303
for repo_name, (platform_name, platform_info) in register_result.impl_repos.items():
305304
toolchain_impls.append(struct(
306305
# str: The base name to use for the toolchain() target
@@ -319,17 +318,21 @@ def _python_impl(module_ctx):
319318
set_python_version_constraint = is_last,
320319
))
321320
if _is_compatible_with_host(module_ctx, platform_info):
322-
host_key = str(len(host_platforms))
323-
host_platforms.append(platform_name)
324-
host_os_names[host_key] = platform_info.os_name
325-
host_archs[host_key] = platform_info.arch
321+
host_platforms[platform_name] = platform_info
326322

323+
host_platforms = sorted_host_platforms(host_platforms)
327324
host_toolchain(
328325
name = toolchain_info.name + "_host",
329326
# NOTE: Order matters. The first found to be compatible is (usually) used.
330-
platforms = host_platforms,
331-
os_names = host_os_names,
332-
archs = host_archs,
327+
platforms = host_platforms.keys(),
328+
os_names = {
329+
str(i): platform_info.os_name
330+
for i, platform_info in enumerate(host_platforms.values())
331+
},
332+
archs = {
333+
str(i): platform_info.arch
334+
for i, platform_info in enumerate(host_platforms.values())
335+
},
333336
python_version = full_python_version,
334337
)
335338

python/private/toolchains_repo.bzl

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ platform-specific repositories.
2525

2626
load(
2727
"//python:versions.bzl",
28+
"FREETHREADED",
29+
"MUSL",
2830
"PLATFORMS",
2931
"WINDOWS_NAME",
3032
)
@@ -436,6 +438,46 @@ multi_toolchain_aliases = repository_rule(
436438
def sanitize_platform_name(platform):
437439
return platform.replace("-", "_")
438440

441+
def sorted_host_platforms(platform_map):
442+
"""Sort the keys in the platform map to give correct precedence.
443+
444+
The order of keys in the platform mapping matters for the host toolchain
445+
selection. When multiple runtimes are compatible with the host, we take the
446+
first that is compatible (usually; there's also the
447+
`RULES_PYTHON_REPO_TOOLCHAIN_*` environment variables). The historical
448+
behavior carefully constructed the ordering of platform keys such that
449+
the ordering was:
450+
* Regular platforms
451+
* The "-freethreaded" suffix
452+
* The "-musl" suffix
453+
454+
Here, we formalize that so it isn't subtly encoded in the ordering of keys
455+
in a dict that autoformatters like to clobber and whose only documentation
456+
is an innocous looking formatter disable directive.
457+
458+
Args:
459+
platform_map: a mapping of platforms and their metadata.
460+
461+
Returns:
462+
dict; the same values, but with the keys inserted in the desired
463+
order so that iteration happens in the desired order.
464+
"""
465+
466+
def platform_keyer(name):
467+
# Ascending sort: lower is higher precedence
468+
pref = 0
469+
if name.endswith("-" + FREETHREADED):
470+
pref = 1
471+
elif name.endswith("-" + MUSL):
472+
pref = 2
473+
return (pref, name)
474+
475+
sorted_platform_keys = sorted(platform_map.keys(), key = platform_keyer)
476+
return {
477+
key: platform_map[key]
478+
for key in sorted_platform_keys
479+
}
480+
439481
def _get_host_platform(*, rctx, logger, python_version, os_name, cpu_name, platforms):
440482
"""Gets the host platform.
441483
@@ -458,7 +500,7 @@ def _get_host_platform(*, rctx, logger, python_version, os_name, cpu_name, platf
458500
arch = rctx.attr.archs[key],
459501
)
460502
else:
461-
platform_map = PLATFORMS
503+
platform_map = sorted_host_platforms(PLATFORMS)
462504

463505
candidates = []
464506
for platform in platforms:

python/versions.bzl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@
1919
MACOS_NAME = "osx"
2020
LINUX_NAME = "linux"
2121
WINDOWS_NAME = "windows"
22+
2223
FREETHREADED = "freethreaded"
24+
MUSL = "musl"
2325
INSTALL_ONLY = "install_only"
2426

2527
DEFAULT_RELEASE_BASE_URL = "https://github.com/astral-sh/python-build-standalone/releases/download"

0 commit comments

Comments
 (0)