Skip to content

Commit 818f3e3

Browse files
committed
wip: add notes fix bugs and address comments
1 parent 916556a commit 818f3e3

File tree

4 files changed

+99
-76
lines changed

4 files changed

+99
-76
lines changed

MODULE.bazel

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,12 @@ pip = use_extension("//python/extensions:pip.bzl", "pip")
7474
env = {"platform_version": "0"},
7575
os_name = "linux",
7676
platform = "linux_{}".format(cpu),
77-
platform_tags = [
77+
whl_abi_tags = [
78+
"cp{major}{minor}",
79+
"abi3",
80+
"none",
81+
],
82+
whl_platform_tags = [
7883
"linux_*_{}".format(cpu),
7984
"manylinux_*_{}".format(cpu),
8085
],
@@ -103,7 +108,12 @@ pip = use_extension("//python/extensions:pip.bzl", "pip")
103108
env = {"platform_version": "14.0"},
104109
os_name = "osx",
105110
platform = "osx_{}".format(cpu),
106-
platform_tags = [
111+
whl_abi_tags = [
112+
"cp{major}{minor}",
113+
"abi3",
114+
"none",
115+
],
116+
whl_platform_tags = [
107117
"macosx_*_{}".format(suffix)
108118
for suffix in platform_tag_cpus
109119
],
@@ -129,7 +139,12 @@ pip.default(
129139
env = {"platform_version": "0"},
130140
os_name = "windows",
131141
platform = "windows_x86_64",
132-
platform_tags = ["win_amd64"],
142+
whl_abi_tags = [
143+
"cp{major}{minor}",
144+
"abi3",
145+
"none",
146+
],
147+
whl_platform_tags = ["win_amd64"],
133148
)
134149
pip.parse(
135150
# NOTE @aignas 2024-10-26: We have an integration test that depends on us

python/private/pypi/extension.bzl

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,23 @@ def _whl_mods_impl(whl_mods_dict):
6868

6969
def _platforms(*, python_version, minor_mapping, config):
7070
platforms = {}
71-
python_version = full_version(
72-
version = python_version,
73-
minor_mapping = minor_mapping,
71+
python_version = version.parse(
72+
full_version(
73+
version = python_version,
74+
minor_mapping = minor_mapping,
75+
),
76+
strict = True,
7477
)
7578

7679
for platform, values in config.platforms.items():
80+
# TODO @aignas 2025-07-07: fix the logic here
7781
implementation = values.env["implementation_name"][:2].lower()
78-
abi = "{}3{}".format(implementation, python_version[2:])
82+
83+
# TODO @aignas 2025-07-07: move the abi construction somewhere else
84+
abi = "{impl}{0}{1}.{2}".format(
85+
impl = implementation,
86+
*python_version.release
87+
)
7988
key = "{}_{}".format(abi, platform)
8089

8190
env_ = env(struct(
@@ -86,10 +95,13 @@ def _platforms(*, python_version, minor_mapping, config):
8695
platforms[key] = struct(
8796
env = env_,
8897
want_abis = [
89-
v.format(*python_version.split("."))
90-
for v in values.want_abis
98+
v.format(
99+
major = python_version.release[0],
100+
minor = python_version.release[1],
101+
)
102+
for v in values.whl_abi_tags
91103
],
92-
platform_tags = values.platform_tags,
104+
platform_tags = values.whl_platform_tags,
93105
)
94106
return platforms
95107

@@ -385,10 +397,10 @@ def _whl_repo(*, src, whl_library_args, is_multiple_versions, download_only, net
385397
),
386398
)
387399

388-
def _configure(config, *, platform, os_name, arch_name, config_settings, env = {}, want_abis, platform_tags, override = False):
400+
def _configure(config, *, platform, os_name, arch_name, config_settings, env = {}, whl_abi_tags, whl_platform_tags, override = False):
389401
"""Set the value in the config if the value is provided"""
390402
config.setdefault("platforms", {})
391-
if platform and (os_name or arch_name or config_settings or platform_tags or env):
403+
if platform and (os_name or arch_name or config_settings or whl_platform_tags or env):
392404
if not override and config.get("platforms", {}).get(platform):
393405
return
394406

@@ -402,21 +414,21 @@ def _configure(config, *, platform, os_name, arch_name, config_settings, env = {
402414
if not arch_name:
403415
fail("'arch_name' is required")
404416

405-
if platform_tags and "any" not in platform_tags:
417+
if whl_platform_tags and "any" not in whl_platform_tags:
406418
# the lowest priority one needs to be the first one
407-
platform_tags = ["any"] + platform_tags
419+
whl_platform_tags = ["any"] + whl_platform_tags
408420

409421
config["platforms"][platform] = struct(
410422
name = platform.replace("-", "_").lower(),
411423
os_name = os_name,
412424
arch_name = arch_name,
413425
config_settings = config_settings,
414-
want_abis = want_abis or [
415-
"cp{0}{1}",
426+
whl_abi_tags = whl_abi_tags or [
427+
"cp{major}{minor}",
416428
"abi3",
417429
"none",
418430
],
419-
platform_tags = platform_tags,
431+
whl_platform_tags = whl_platform_tags,
420432
env = {
421433
# default to this
422434
"implementation_name": "cpython",
@@ -491,8 +503,8 @@ You cannot use both the additive_build_content and additive_build_content_file a
491503
env = tag.env,
492504
os_name = tag.os_name,
493505
platform = tag.platform,
494-
platform_tags = tag.platform_tags,
495-
want_abis = tag.want_abis,
506+
whl_abi_tags = tag.whl_abi_tags,
507+
whl_platform_tags = tag.whl_platform_tags,
496508
override = mod.is_root,
497509
# TODO @aignas 2025-05-19: add more attr groups:
498510
# * for AUTH - the default `netrc` usage could be configured through a common
@@ -844,20 +856,24 @@ If you are defining custom platforms in your project and don't want things to cl
844856
[isolation]: https://bazel.build/rules/lib/globals/module#use_extension.isolate
845857
""",
846858
),
847-
"platform_tags": attr.string_list(
859+
"whl_abi_tags": attr.string_list(
860+
doc = """\
861+
A list of ABIs to select wheels for. The values can be either strings or include template
862+
parameters like `{0}` which will be replaced with python version parts. e.g. `cp{0}{1}` will
863+
result in `cp313` given the full python version is `3.13.5`.
864+
865+
See official [docs](https://packaging.python.org/en/latest/specifications/platform-compatibility-tags/#abi-tag) for more information.
866+
""",
867+
),
868+
"whl_platform_tags": attr.string_list(
848869
doc = """\
849870
A list of `platform_tag` matchers so that we can select the best wheel based on the user
850871
preference. Per platform we will select a single wheel and the last match from this list will
851872
take precedence.
852873
853874
The items in this list can contain a single `*` character that is equivalent to `.*` regex match.
854-
""",
855-
),
856-
"want_abis": attr.string_list(
857-
doc = """\
858-
A list of ABIs to select wheels for. The values can be either strings or include template
859-
parameters like `{0}` which will be replaced with python version parts. e.g. `cp{0}{1}` will
860-
result in `cp313` given the full python version is `3.13.5`.
875+
876+
See official [docs](https://packaging.python.org/en/latest/specifications/platform-compatibility-tags/#platform-tag) for more information.
861877
""",
862878
),
863879
}

python/private/pypi/pep508_env.bzl

Lines changed: 33 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
"""This module is for implementing PEP508 environment definition.
1616
"""
1717

18+
_DEFAULT = "//conditions:default"
19+
1820
# See https://stackoverflow.com/a/45125525
1921
platform_machine_aliases = {
2022
# These pairs mean the same hardware, but different values may be used
@@ -59,11 +61,11 @@ platform_machine_select_map = {
5961
"@platforms//cpu:x86_64": "x86_64",
6062
# The value is empty string if it cannot be determined:
6163
# https://docs.python.org/3/library/platform.html#platform.machine
62-
"//conditions:default": "",
64+
_DEFAULT: "",
6365
}
6466

6567
# Platform system returns results from the `uname` call.
66-
_platform_system_values = {
68+
platform_system_select_map = {
6769
# See https://peps.python.org/pep-0738/#platform
6870
"android": "Android",
6971
"freebsd": "FreeBSD",
@@ -75,15 +77,9 @@ _platform_system_values = {
7577
"openbsd": "OpenBSD",
7678
"osx": "Darwin",
7779
"windows": "Windows",
78-
}
79-
80-
platform_system_select_map = {
81-
"@platforms//os:{}".format(bazel_os): py_system
82-
for bazel_os, py_system in _platform_system_values.items()
83-
} | {
8480
# The value is empty string if it cannot be determined:
8581
# https://docs.python.org/3/library/platform.html#platform.machine
86-
"//conditions:default": "",
82+
_DEFAULT: "",
8783
}
8884

8985
# The copy of SO [answer](https://stackoverflow.com/a/13874620) containing
@@ -111,50 +107,43 @@ platform_system_select_map = {
111107
# (**) Prior Python 3.8 could also be aix5 or aix7; use sys.platform.startswith()
112108
#
113109
# We are using only the subset that we actually support.
114-
_sys_platform_values = {
110+
sys_platform_select_map = {
115111
# These values are decided by the sys.platform docs.
116-
"android": "android",
117-
"emscripten": "emscripten",
112+
"@platforms//os:android": "android",
113+
"@platforms//os:emscripten": "emscripten",
118114
# NOTE: The below values are approximations. The sys.platform() docs
119115
# don't have documented values for these OSes. Per docs, the
120116
# sys.platform() value reflects the OS at the time Python was *built*
121117
# instead of the runtime (target) OS value.
122-
"freebsd": "freebsd",
123-
"ios": "ios",
124-
"linux": "linux",
125-
"openbsd": "openbsd",
126-
"osx": "darwin",
127-
"wasi": "wasi",
128-
"windows": "win32",
129-
}
130-
131-
sys_platform_select_map = {
132-
"@platforms//os:{}".format(bazel_os): py_platform
133-
for bazel_os, py_platform in _sys_platform_values.items()
134-
} | {
118+
"@platforms//os:freebsd": "freebsd",
119+
"@platforms//os:ios": "ios",
120+
"@platforms//os:linux": "linux",
121+
"@platforms//os:openbsd": "openbsd",
122+
"@platforms//os:osx": "darwin",
123+
"@platforms//os:wasi": "wasi",
124+
"@platforms//os:windows": "win32",
135125
# For lack of a better option, use empty string. No standard doc/spec
136126
# about sys_platform value.
137-
"//conditions:default": "",
127+
_DEFAULT: "",
138128
}
139129

140130
# The "java" value is documented, but with Jython defunct,
141131
# shouldn't occur in practice.
142132
# The os.name value is technically a property of the runtime, not the
143133
# targetted runtime OS, but the distinction shouldn't matter if
144134
# things are properly configured.
145-
_os_name_values = {
146-
"linux": "posix",
147-
"osx": "posix",
148-
"windows": "nt",
149-
}
150-
151135
os_name_select_map = {
152-
"@platforms//os:{}".format(bazel_os): py_os
153-
for bazel_os, py_os in _os_name_values.items()
154-
} | {
155-
"//conditions:default": "posix",
136+
"@platforms//os:windows": "nt",
137+
_DEFAULT: "posix",
156138
}
157139

140+
# TODO @aignas 2025-07-07: add a test to ensure that this is tested
141+
def _get_from_map(m, key):
142+
if _DEFAULT in m:
143+
return m.get(key, m[_DEFAULT])
144+
else:
145+
return m[key]
146+
158147
def env(target_platform, *, extra = None):
159148
"""Return an env target platform
160149
@@ -174,20 +163,23 @@ def env(target_platform, *, extra = None):
174163
env["extra"] = extra
175164

176165
if target_platform.abi:
166+
# TODO @aignas 2025-07-07: do not parse the version like this here
177167
minor_version, _, micro_version = target_platform.abi[3:].partition(".")
178168
micro_version = micro_version or "0"
179169
env = env | {
180170
"implementation_version": "3.{}.{}".format(minor_version, micro_version),
181171
"python_full_version": "3.{}.{}".format(minor_version, micro_version),
182172
"python_version": "3.{}".format(minor_version),
183173
}
174+
184175
if target_platform.os and target_platform.arch:
185-
os = target_platform.os
176+
os = "@platforms//os:{}".format(target_platform.os)
177+
arch = "@platforms//cpu:{}".format(target_platform.arch)
186178
env = env | {
187-
"os_name": _os_name_values.get(os, ""),
188-
"platform_machine": target_platform.arch,
189-
"platform_system": _platform_system_values.get(os, ""),
190-
"sys_platform": _sys_platform_values.get(os, ""),
179+
"os_name": _get_from_map(os_name_select_map, os),
180+
"platform_machine": _get_from_map(platform_machine_select_map, arch),
181+
"platform_system": _get_from_map(platform_system_select_map, os),
182+
"sys_platform": _get_from_map(sys_platform_select_map, os),
191183
}
192184
set_missing_env_defaults(env)
193185

tests/pypi/extension/extension_tests.bzl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@ def _mod(*, name, default = [], parse = [], override = [], whl_mods = [], is_roo
6565
"@platforms//os:{}".format(os),
6666
"@platforms//cpu:{}".format(cpu),
6767
],
68-
platform_tags = platform_tags,
68+
whl_platform_tags = whl_platform_tags,
6969
)
70-
for (os, cpu), platform_tags in {
70+
for (os, cpu), whl_platform_tags in {
7171
("linux", "x86_64"): ["linux_*_x86_64", "manylinux_*_x86_64"],
7272
("linux", "aarch64"): ["linux_*_aarch64", "manylinux_*_aarch64"],
7373
("osx", "aarch64"): ["macosx_*_arm64"],
@@ -99,17 +99,17 @@ def _default(
9999
config_settings = None,
100100
os_name = None,
101101
platform = None,
102-
platform_tags = None,
102+
whl_platform_tags = None,
103103
env = None,
104-
want_abis = None):
104+
whl_abi_tags = None):
105105
return struct(
106106
arch_name = arch_name,
107107
os_name = os_name,
108108
platform = platform,
109-
platform_tags = platform_tags or [],
109+
whl_platform_tags = whl_platform_tags or [],
110110
config_settings = config_settings,
111111
env = env or {},
112-
want_abis = want_abis or [],
112+
whl_abi_tags = whl_abi_tags or [],
113113
)
114114

115115
def _parse(
@@ -407,9 +407,9 @@ def _test_torch_experimental_index_url(env):
407407
"@platforms//os:{}".format(os),
408408
"@platforms//cpu:{}".format(cpu),
409409
],
410-
platform_tags = platform_tags,
410+
whl_platform_tags = whl_platform_tags,
411411
)
412-
for (os, cpu), platform_tags in {
412+
for (os, cpu), whl_platform_tags in {
413413
("linux", "x86_64"): ["linux_*_x86_64", "manylinux_*_x86_64"],
414414
("linux", "aarch64"): ["linux_*_aarch64", "manylinux_*_aarch64"],
415415
("osx", "aarch64"): ["macosx_*_arm64"],

0 commit comments

Comments
 (0)