Skip to content

Commit b8d6fa3

Browse files
aignasrickeylev
andauthored
feat(pypi): pip.defaults API for customizing repo selection 2/n (bazel-contrib#2988)
WIP: stacked on bazel-contrib#2987 This is adding `constraint_values` attribute to `pip.configure` and is threading it all the way down to the generation of `BUILD.bazel` file of for config settings used in the hub repository. Out of scope: - Passing `flag_values` or target settings. I am torn about it - doing it in this PR would flesh out the design more, but at the same time it might become harder to review. - `whl_target_platforms` and `select_whls` is still unchanged, not sure if it is related to this attribute addition. Work towards bazel-contrib#2747 Work towards bazel-contrib#2548 Work towards bazel-contrib#260 --------- Co-authored-by: Richard Levasseur <richardlev@gmail.com>
1 parent 5b1db07 commit b8d6fa3

File tree

9 files changed

+140
-42
lines changed

9 files changed

+140
-42
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ END_UNRELEASED_TEMPLATE
6464
### Added
6565
* (pypi) To configure the environment for `requirements.txt` evaluation, use the newly added
6666
developer preview of the `pip.default` tag class. Only `rules_python` and root modules can use
67-
this feature.
67+
this feature. You can also configure `constraint_values` using `pip.default`.
6868

6969
{#v0-0-0-removed}
7070
### Removed

python/private/pypi/config_settings.bzl

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,8 @@ def config_settings(
111111
glibc_versions = [],
112112
muslc_versions = [],
113113
osx_versions = [],
114-
target_platforms = [],
115114
name = None,
115+
platform_constraint_values = {},
116116
**kwargs):
117117
"""Generate all of the pip config settings.
118118
@@ -126,31 +126,28 @@ def config_settings(
126126
configure config settings for.
127127
osx_versions (list[str]): The list of OSX OS versions to configure
128128
config settings for.
129-
target_platforms (list[str]): The list of "{os}_{cpu}" for deriving
130-
constraint values for each condition.
129+
platform_constraint_values: {type}`dict[str, list[str]]` the constraint
130+
values to use instead of the default ones. Key are platform names
131+
(a human-friendly platform string). Values are lists of
132+
`constraint_value` label strings.
131133
**kwargs: Other args passed to the underlying implementations, such as
132134
{obj}`native`.
133135
"""
134136

135137
glibc_versions = [""] + glibc_versions
136138
muslc_versions = [""] + muslc_versions
137139
osx_versions = [""] + osx_versions
138-
target_platforms = [("", ""), ("osx", "universal2")] + [
139-
t.split("_", 1)
140-
for t in target_platforms
141-
]
140+
target_platforms = {
141+
"": [],
142+
# TODO @aignas 2025-06-15: allowing universal2 and platform specific wheels in one
143+
# closure is making things maybe a little bit too complicated.
144+
"osx_universal2": ["@platforms//os:osx"],
145+
} | platform_constraint_values
142146

143147
for python_version in python_versions:
144-
for os, cpu in target_platforms:
145-
constraint_values = []
146-
suffix = ""
147-
if os:
148-
constraint_values.append("@platforms//os:" + os)
149-
suffix += "_" + os
150-
if cpu:
151-
suffix += "_" + cpu
152-
if cpu != "universal2":
153-
constraint_values.append("@platforms//cpu:" + cpu)
148+
for platform_name, constraint_values in target_platforms.items():
149+
suffix = "_{}".format(platform_name) if platform_name else ""
150+
os, _, cpu = platform_name.partition("_")
154151

155152
_dist_config_settings(
156153
suffix = suffix,

python/private/pypi/extension.bzl

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ def _whl_repo(*, src, whl_library_args, is_multiple_versions, download_only, net
372372
),
373373
)
374374

375-
def _configure(config, *, platform, os_name, arch_name, override = False, env = {}):
375+
def _configure(config, *, platform, os_name, arch_name, constraint_values, env = {}, override = False):
376376
"""Set the value in the config if the value is provided"""
377377
config.setdefault("platforms", {})
378378
if platform:
@@ -387,6 +387,7 @@ def _configure(config, *, platform, os_name, arch_name, override = False, env =
387387
name = platform.replace("-", "_").lower(),
388388
os_name = os_name,
389389
arch_name = arch_name,
390+
constraint_values = constraint_values,
390391
env = env,
391392
)
392393
else:
@@ -413,6 +414,10 @@ def _create_config(defaults):
413414
arch_name = cpu,
414415
os_name = "linux",
415416
platform = "linux_{}".format(cpu),
417+
constraint_values = [
418+
"@platforms//os:linux",
419+
"@platforms//cpu:{}".format(cpu),
420+
],
416421
env = {"platform_version": "0"},
417422
)
418423
for cpu in [
@@ -424,17 +429,25 @@ def _create_config(defaults):
424429
arch_name = cpu,
425430
# We choose the oldest non-EOL version at the time when we release `rules_python`.
426431
# See https://endoflife.date/macos
427-
env = {"platform_version": "14.0"},
428432
os_name = "osx",
429433
platform = "osx_{}".format(cpu),
434+
constraint_values = [
435+
"@platforms//os:osx",
436+
"@platforms//cpu:{}".format(cpu),
437+
],
438+
env = {"platform_version": "14.0"},
430439
)
431440

432441
_configure(
433442
defaults,
434443
arch_name = "x86_64",
435-
env = {"platform_version": "0"},
436444
os_name = "windows",
437445
platform = "windows_x86_64",
446+
constraint_values = [
447+
"@platforms//os:windows",
448+
"@platforms//cpu:x86_64",
449+
],
450+
env = {"platform_version": "0"},
438451
)
439452
return struct(**defaults)
440453

@@ -500,6 +513,7 @@ You cannot use both the additive_build_content and additive_build_content_file a
500513
_configure(
501514
defaults,
502515
arch_name = tag.arch_name,
516+
constraint_values = tag.constraint_values,
503517
env = tag.env,
504518
os_name = tag.os_name,
505519
platform = tag.platform,
@@ -679,6 +693,13 @@ You cannot use both the additive_build_content and additive_build_content_file a
679693
}
680694
for hub_name, extra_whl_aliases in extra_aliases.items()
681695
},
696+
platform_constraint_values = {
697+
hub_name: {
698+
platform_name: sorted([str(Label(cv)) for cv in p.constraint_values])
699+
for platform_name, p in config.platforms.items()
700+
}
701+
for hub_name in hub_whl_map
702+
},
682703
whl_libraries = {
683704
k: dict(sorted(args.items()))
684705
for k, args in sorted(whl_libraries.items())
@@ -769,6 +790,7 @@ def _pip_impl(module_ctx):
769790
for key, values in whl_map.items()
770791
},
771792
packages = mods.exposed_packages.get(hub_name, []),
793+
platform_constraint_values = mods.platform_constraint_values.get(hub_name, {}),
772794
groups = mods.hub_group_map.get(hub_name),
773795
)
774796

@@ -788,6 +810,12 @@ The CPU architecture name to be used.
788810
:::{note}
789811
Either this or {attr}`env` `platform_machine` key should be specified.
790812
:::
813+
""",
814+
),
815+
"constraint_values": attr.label_list(
816+
mandatory = True,
817+
doc = """\
818+
The constraint_values to use in select statements.
791819
""",
792820
),
793821
"os_name": attr.string(

python/private/pypi/hub_repository.bzl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ def _impl(rctx):
3434
},
3535
extra_hub_aliases = rctx.attr.extra_hub_aliases,
3636
requirement_cycles = rctx.attr.groups,
37+
platform_constraint_values = rctx.attr.platform_constraint_values,
3738
)
3839
for path, contents in aliases.items():
3940
rctx.file(path, contents)
@@ -83,6 +84,10 @@ hub_repository = repository_rule(
8384
The list of packages that will be exposed via all_*requirements macros. Defaults to whl_map keys.
8485
""",
8586
),
87+
"platform_constraint_values": attr.string_list_dict(
88+
doc = "The constraint values for each platform name. The values are string canonical string Label representations",
89+
mandatory = False,
90+
),
8691
"repo_name": attr.string(
8792
mandatory = True,
8893
doc = "The apparent name of the repo. This is needed because in bzlmod, the name attribute becomes the canonical name.",

python/private/pypi/render_pkg_aliases.bzl

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -155,12 +155,14 @@ def _major_minor_versions(python_versions):
155155
# Use a dict as a simple set
156156
return sorted({_major_minor(v): None for v in python_versions})
157157

158-
def render_multiplatform_pkg_aliases(*, aliases, **kwargs):
158+
def render_multiplatform_pkg_aliases(*, aliases, platform_constraint_values = {}, **kwargs):
159159
"""Render the multi-platform pkg aliases.
160160
161161
Args:
162162
aliases: dict[str, list(whl_config_setting)] A list of aliases that will be
163163
transformed from ones having `filename` to ones having `config_setting`.
164+
platform_constraint_values: {type}`dict[str, list[str]]` contains all of the
165+
target platforms and their appropriate `constraint_values`.
164166
**kwargs: extra arguments passed to render_pkg_aliases.
165167
166168
Returns:
@@ -187,18 +189,22 @@ def render_multiplatform_pkg_aliases(*, aliases, **kwargs):
187189
muslc_versions = flag_versions.get("muslc_versions", []),
188190
osx_versions = flag_versions.get("osx_versions", []),
189191
python_versions = _major_minor_versions(flag_versions.get("python_versions", [])),
190-
target_platforms = flag_versions.get("target_platforms", []),
192+
platform_constraint_values = platform_constraint_values,
191193
visibility = ["//:__subpackages__"],
192194
)
193195
return contents
194196

195-
def _render_config_settings(**kwargs):
197+
def _render_config_settings(platform_constraint_values, **kwargs):
196198
return """\
197199
load("@rules_python//python/private/pypi:config_settings.bzl", "config_settings")
198200
199201
{}""".format(render.call(
200202
"config_settings",
201203
name = repr("config_settings"),
204+
platform_constraint_values = render.dict(
205+
platform_constraint_values,
206+
value_repr = render.list,
207+
),
202208
**_repr_dict(value_repr = render.list, **kwargs)
203209
))
204210

tests/pypi/config_settings/config_settings_tests.bzl

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -657,13 +657,34 @@ def config_settings_test_suite(name): # buildifier: disable=function-docstring
657657
glibc_versions = [(2, 14), (2, 17)],
658658
muslc_versions = [(1, 1)],
659659
osx_versions = [(10, 9), (11, 0)],
660-
target_platforms = [
661-
"windows_x86_64",
662-
"windows_aarch64",
663-
"linux_x86_64",
664-
"linux_ppc",
665-
"linux_aarch64",
666-
"osx_x86_64",
667-
"osx_aarch64",
668-
],
660+
platform_constraint_values = {
661+
"linux_aarch64": [
662+
"@platforms//cpu:aarch64",
663+
"@platforms//os:linux",
664+
],
665+
"linux_ppc": [
666+
"@platforms//cpu:ppc",
667+
"@platforms//os:linux",
668+
],
669+
"linux_x86_64": [
670+
"@platforms//cpu:x86_64",
671+
"@platforms//os:linux",
672+
],
673+
"osx_aarch64": [
674+
"@platforms//cpu:aarch64",
675+
"@platforms//os:osx",
676+
],
677+
"osx_x86_64": [
678+
"@platforms//cpu:x86_64",
679+
"@platforms//os:osx",
680+
],
681+
"windows_aarch64": [
682+
"@platforms//cpu:aarch64",
683+
"@platforms//os:windows",
684+
],
685+
"windows_x86_64": [
686+
"@platforms//cpu:x86_64",
687+
"@platforms//os:windows",
688+
],
689+
},
669690
)

tests/pypi/extension/extension_tests.bzl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,6 +1051,10 @@ def _test_pipstar_platforms(env):
10511051
default = [
10521052
_default(
10531053
platform = "{}_{}".format(os, cpu),
1054+
constraint_values = [
1055+
"@platforms//os:{}".format(os),
1056+
"@platforms//cpu:{}".format(cpu),
1057+
],
10541058
)
10551059
for os, cpu in [
10561060
("linux", "x86_64"),

tests/pypi/pkg_aliases/pkg_aliases_test.bzl

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -419,10 +419,16 @@ def _test_config_settings_exist_legacy(env):
419419
alias = _mock_alias(available_config_settings),
420420
config_setting = _mock_config_setting(available_config_settings),
421421
),
422-
target_platforms = [
423-
"linux_aarch64",
424-
"linux_x86_64",
425-
],
422+
platform_constraint_values = {
423+
"linux_aarch64": [
424+
"@platforms//cpu:aarch64",
425+
"@platforms//os:linux",
426+
],
427+
"linux_x86_64": [
428+
"@platforms//cpu:x86_64",
429+
"@platforms//os:linux",
430+
],
431+
},
426432
)
427433

428434
got_aliases = multiplatform_whl_aliases(
@@ -448,19 +454,39 @@ def _test_config_settings_exist(env):
448454
"any": {},
449455
"macosx_11_0_arm64": {
450456
"osx_versions": [(11, 0)],
451-
"target_platforms": ["osx_aarch64"],
457+
"platform_constraint_values": {
458+
"osx_aarch64": [
459+
"@platforms//cpu:aarch64",
460+
"@platforms//os:osx",
461+
],
462+
},
452463
},
453464
"manylinux_2_17_x86_64": {
454465
"glibc_versions": [(2, 17), (2, 18)],
455-
"target_platforms": ["linux_x86_64"],
466+
"platform_constraint_values": {
467+
"linux_x86_64": [
468+
"@platforms//cpu:x86_64",
469+
"@platforms//os:linux",
470+
],
471+
},
456472
},
457473
"manylinux_2_18_x86_64": {
458474
"glibc_versions": [(2, 17), (2, 18)],
459-
"target_platforms": ["linux_x86_64"],
475+
"platform_constraint_values": {
476+
"linux_x86_64": [
477+
"@platforms//cpu:x86_64",
478+
"@platforms//os:linux",
479+
],
480+
},
460481
},
461482
"musllinux_1_1_aarch64": {
462483
"muslc_versions": [(1, 2), (1, 1), (1, 0)],
463-
"target_platforms": ["linux_aarch64"],
484+
"platform_constraint_values": {
485+
"linux_aarch64": [
486+
"@platforms//cpu:aarch64",
487+
"@platforms//os:linux",
488+
],
489+
},
464490
},
465491
}.items():
466492
aliases = {

tests/pypi/render_pkg_aliases/render_pkg_aliases_test.bzl

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,12 @@ def _test_bzlmod_aliases(env):
9393
},
9494
},
9595
extra_hub_aliases = {"bar_baz": ["foo"]},
96+
platform_constraint_values = {
97+
"linux_x86_64": [
98+
"@platforms//os:linux",
99+
"@platforms//cpu:x86_64",
100+
],
101+
},
96102
)
97103

98104
want_key = "bar_baz/BUILD.bazel"
@@ -130,8 +136,13 @@ load("@rules_python//python/private/pypi:config_settings.bzl", "config_settings"
130136
131137
config_settings(
132138
name = "config_settings",
139+
platform_constraint_values = {
140+
"linux_x86_64": [
141+
"@platforms//os:linux",
142+
"@platforms//cpu:x86_64",
143+
],
144+
},
133145
python_versions = ["3.2"],
134-
target_platforms = ["linux_x86_64"],
135146
visibility = ["//:__subpackages__"],
136147
)""",
137148
)

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