Skip to content

Commit 6d83314

Browse files
committed
feat(pypi): incrementally build platform configuration
Before this PR the configuration for platforms would be built non-incrementally, making it harder for users to override particular attributes of the already configured ones. With this PR the new features introduced in bazel-contrib#3058 will be easier to override. Work towards bazel-contrib#2747
1 parent f02c9c7 commit 6d83314

File tree

2 files changed

+128
-36
lines changed

2 files changed

+128
-36
lines changed

python/private/pypi/extension.bzl

Lines changed: 76 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -379,24 +379,90 @@ def _whl_repo(*, src, whl_library_args, is_multiple_versions, download_only, net
379379
def _configure(config, *, platform, os_name, arch_name, config_settings, env = {}, override = False):
380380
"""Set the value in the config if the value is provided"""
381381
config.setdefault("platforms", {})
382-
if platform:
382+
if platform and (os_name or arch_name or config_settings or env):
383383
if not override and config.get("platforms", {}).get(platform):
384384
return
385385

386386
for key in env:
387387
if key not in _SUPPORTED_PEP508_KEYS:
388388
fail("Unsupported key in the PEP508 environment: {}".format(key))
389389

390-
config["platforms"][platform] = struct(
391-
name = platform.replace("-", "_").lower(),
392-
os_name = os_name,
393-
arch_name = arch_name,
394-
config_settings = config_settings,
395-
env = env,
396-
)
390+
config["platforms"].setdefault(platform, {})
391+
for key, value in {
392+
"arch_name": arch_name,
393+
"config_settings": config_settings,
394+
"env": env,
395+
"name": platform.replace("-", "_").lower(),
396+
"os_name": os_name,
397+
}.items():
398+
if not value:
399+
continue
400+
401+
if not override and config.get(key):
402+
continue
403+
404+
config["platforms"][platform][key] = value
397405
else:
398406
config["platforms"].pop(platform)
399407

408+
def _plat(*, name, arch_name, os_name, config_settings = [], env = {}):
409+
return struct(
410+
name = name,
411+
arch_name = arch_name,
412+
os_name = os_name,
413+
config_settings = config_settings,
414+
env = env,
415+
)
416+
417+
def build_config(
418+
*,
419+
module_ctx,
420+
enable_pipstar):
421+
"""Parse 'configure' and 'default' extension tags
422+
423+
Args:
424+
module_ctx: {type}`module_ctx` module context.
425+
enable_pipstar: {type}`bool` a flag to enable dropping Python dependency for
426+
evaluation of the extension.
427+
428+
Returns:
429+
A struct with the configuration.
430+
"""
431+
defaults = {
432+
"platforms": {},
433+
}
434+
for mod in module_ctx.modules:
435+
if not (mod.is_root or mod.name == "rules_python"):
436+
continue
437+
438+
platform = None
439+
for tag in mod.tags.default:
440+
platform = tag.platform or platform
441+
_configure(
442+
defaults,
443+
arch_name = tag.arch_name,
444+
config_settings = tag.config_settings,
445+
env = tag.env,
446+
os_name = tag.os_name,
447+
platform = platform,
448+
override = mod.is_root,
449+
# TODO @aignas 2025-05-19: add more attr groups:
450+
# * for AUTH - the default `netrc` usage could be configured through a common
451+
# attribute.
452+
# * for index/downloader config. This includes all of those attributes for
453+
# overrides, etc. Index overrides per platform could be also used here.
454+
# * for whl selection - selecting preferences of which `platform_tag`s we should use
455+
# for what. We could also model the `cp313t` freethreaded as separate platforms.
456+
)
457+
458+
return struct(
459+
platforms = {
460+
name: _plat(**values)
461+
for name, values in defaults["platforms"].items()
462+
},
463+
enable_pipstar = enable_pipstar,
464+
)
465+
400466
def parse_modules(
401467
module_ctx,
402468
_fail = fail,
@@ -447,33 +513,7 @@ You cannot use both the additive_build_content and additive_build_content_file a
447513
srcs_exclude_glob = whl_mod.srcs_exclude_glob,
448514
)
449515

450-
defaults = {
451-
"enable_pipstar": enable_pipstar,
452-
"platforms": {},
453-
}
454-
for mod in module_ctx.modules:
455-
if not (mod.is_root or mod.name == "rules_python"):
456-
continue
457-
458-
for tag in mod.tags.default:
459-
_configure(
460-
defaults,
461-
arch_name = tag.arch_name,
462-
config_settings = tag.config_settings,
463-
env = tag.env,
464-
os_name = tag.os_name,
465-
platform = tag.platform,
466-
override = mod.is_root,
467-
# TODO @aignas 2025-05-19: add more attr groups:
468-
# * for AUTH - the default `netrc` usage could be configured through a common
469-
# attribute.
470-
# * for index/downloader config. This includes all of those attributes for
471-
# overrides, etc. Index overrides per platform could be also used here.
472-
# * for whl selection - selecting preferences of which `platform_tag`s we should use
473-
# for what. We could also model the `cp313t` freethreaded as separate platforms.
474-
)
475-
476-
config = struct(**defaults)
516+
config = build_config(module_ctx = module_ctx, enable_pipstar = enable_pipstar)
477517

478518
# TODO @aignas 2025-06-03: Merge override API with the builder?
479519
_overriden_whl_set = {}
@@ -650,6 +690,7 @@ You cannot use both the additive_build_content and additive_build_content_file a
650690
k: dict(sorted(args.items()))
651691
for k, args in sorted(whl_libraries.items())
652692
},
693+
config = config,
653694
)
654695

655696
def _pip_impl(module_ctx):

tests/pypi/extension/extension_tests.bzl

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
load("@rules_testing//lib:test_suite.bzl", "test_suite")
1818
load("@rules_testing//lib:truth.bzl", "subjects")
19-
load("//python/private/pypi:extension.bzl", "parse_modules") # buildifier: disable=bzl-visibility
19+
load("//python/private/pypi:extension.bzl", "build_config", "parse_modules") # buildifier: disable=bzl-visibility
2020
load("//python/private/pypi:parse_simpleapi_html.bzl", "parse_simpleapi_html") # buildifier: disable=bzl-visibility
2121
load("//python/private/pypi:whl_config_setting.bzl", "whl_config_setting") # buildifier: disable=bzl-visibility
2222

@@ -92,6 +92,18 @@ def _parse_modules(env, enable_pipstar = 0, **kwargs):
9292
),
9393
)
9494

95+
def _build_config(env, enable_pipstar = 0, **kwargs):
96+
return env.expect.that_struct(
97+
build_config(
98+
enable_pipstar = enable_pipstar,
99+
**kwargs
100+
),
101+
attrs = dict(
102+
platforms = subjects.dict,
103+
enable_pipstar = subjects.bool,
104+
),
105+
)
106+
95107
def _default(
96108
arch_name = None,
97109
config_settings = None,
@@ -1108,6 +1120,45 @@ optimum[onnxruntime-gpu]==1.17.1 ; sys_platform == 'linux'
11081120

11091121
_tests.append(_test_pipstar_platforms)
11101122

1123+
def _test_build_pipstar_platform(env):
1124+
config = _build_config(
1125+
env,
1126+
module_ctx = _mock_mctx(
1127+
_mod(
1128+
name = "rules_python",
1129+
default = [
1130+
_default(
1131+
platform = "myplat",
1132+
os_name = "linux",
1133+
arch_name = "x86_64",
1134+
),
1135+
_default(
1136+
config_settings = [
1137+
"@platforms//os:linux",
1138+
"@platforms//cpu:x86_64",
1139+
],
1140+
),
1141+
],
1142+
),
1143+
),
1144+
enable_pipstar = True,
1145+
)
1146+
config.enable_pipstar().equals(True)
1147+
config.platforms().contains_exactly({
1148+
"myplat": struct(
1149+
name = "myplat",
1150+
os_name = "linux",
1151+
arch_name = "x86_64",
1152+
config_settings = [
1153+
"@platforms//os:linux",
1154+
"@platforms//cpu:x86_64",
1155+
],
1156+
env = {},
1157+
),
1158+
})
1159+
1160+
_tests.append(_test_build_pipstar_platform)
1161+
11111162
def extension_test_suite(name):
11121163
"""Create the test suite.
11131164

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