Skip to content

Commit b340de7

Browse files
committed
code share with pep508_env.bzl, add config_setting,
1 parent 7ff220e commit b340de7

File tree

3 files changed

+133
-125
lines changed

3 files changed

+133
-125
lines changed

python/private/pypi/env_marker_setting.bzl

Lines changed: 39 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -2,121 +2,48 @@
22

33
load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo")
44
load("//python/private:toolchain_types.bzl", "TARGET_TOOLCHAIN_TYPE")
5+
load(
6+
":pep508_env.bzl",
7+
"env_aliases",
8+
"os_name_select_map",
9+
"platform_machine_aliases",
10+
"platform_machine_select_map",
11+
"platform_system_select_map",
12+
"sys_platform_select_map",
13+
)
514
load(":pep508_evaluate.bzl", "evaluate")
615

7-
# todo: copied from pep508_env.bzl
8-
_os_name_select_map = {
9-
# The "java" value is documented, but with Jython defunct,
10-
# shouldn't occur in practice.
11-
# The os.name value is technically a property of the runtime, not the
12-
# targetted runtime OS, but the distinction shouldn't matter if
13-
# things are properly configured.
14-
"@platforms//os:windows": "nt",
15-
"//conditions:default": "posix",
16-
}
17-
18-
# TODO @aignas 2025-04-29: this is copied from ./pep508_env.bzl
19-
_platform_machine_aliases = {
20-
# These pairs mean the same hardware, but different values may be used
21-
# on different host platforms.
22-
"amd64": "x86_64",
23-
"arm64": "aarch64",
24-
"i386": "x86_32",
25-
"i686": "x86_32",
26-
}
27-
28-
# Taken from
29-
# https://docs.python.org/3/library/sys.html#sys.platform
30-
_sys_platform_select_map = {
31-
# These values are decided by the sys.platform docs.
32-
"@platforms//os:android": "android",
33-
"@platforms//os:emscripten": "emscripten",
34-
"@platforms//os:ios": "ios",
35-
"@platforms//os:linux": "linux",
36-
"@platforms//os:osx": "darwin",
37-
"@platforms//os:windows": "win32",
38-
"@platforms//os:wasi": "wasi",
39-
# NOTE: The below values are approximations. The sys.platform() docs
40-
# don't have documented values for these OSes. Per docs, the
41-
# sys.platform() value reflects the OS at the time Python was *built*
42-
# instead of the runtime (target) OS value.
43-
"@platforms//os:freebsd": "freebsd",
44-
"@platforms//os:openbsd": "openbsd",
45-
# For lack of a better option, use empty string. No standard doc/spec
46-
# about sys_platform value.
47-
"//conditions:default": "",
48-
}
49-
50-
# todo: copied from pep508_env.bzl
51-
# TODO: there are many cpus and unfortunately, it doesn't look like
52-
# the value is directly accessible to starlark. It might be possible to
53-
# get it via CcToolchain.cpu though.
54-
_platform_machine_select_map = {
55-
"@platforms//cpu:aarch32": "aarch32",
56-
"@platforms//cpu:aarch64": "aarch64",
57-
"@platforms//cpu:arm": "arm",
58-
"@platforms//cpu:arm64": "arm64",
59-
"@platforms//cpu:arm64_32": "arm64_32",
60-
"@platforms//cpu:arm64e": "arm64e",
61-
"@platforms//cpu:armv6-m": "armv6-m",
62-
"@platforms//cpu:armv7": "armv7",
63-
"@platforms//cpu:armv7-m": "armv7-m",
64-
"@platforms//cpu:armv7e-m": "armv7e-m",
65-
"@platforms//cpu:armv7e-mf": "armv7e-mf",
66-
"@platforms//cpu:armv7k": "armv7k",
67-
"@platforms//cpu:armv8-m": "armv8-m",
68-
"@platforms//cpu:cortex-r52": "cortex-r52",
69-
"@platforms//cpu:cortex-r82": "cortex-r82",
70-
"@platforms//cpu:i386": "i386",
71-
"@platforms//cpu:mips64": "mips64",
72-
"@platforms//cpu:ppc": "ppc",
73-
"@platforms//cpu:ppc32": "ppc32",
74-
"@platforms//cpu:ppc64le": "ppc64le",
75-
"@platforms//cpu:riscv32": "riscv32",
76-
"@platforms//cpu:riscv64": "riscv64",
77-
"@platforms//cpu:s390x": "s390x",
78-
"@platforms//cpu:wasm32": "wasm32",
79-
"@platforms//cpu:wasm64": "wasm64",
80-
"@platforms//cpu:x86_32": "x86_32",
81-
"@platforms//cpu:x86_64": "x86_64",
82-
# The value is empty string if it cannot be determined:
83-
# https://docs.python.org/3/library/platform.html#platform.machine
84-
"//conditions:default": "",
85-
}
86-
87-
# todo: copied from pep508_env.bzl
88-
_platform_system_select_map = {
89-
# See https://peps.python.org/pep-0738/#platform
90-
"@platforms//os:android": "Android",
91-
"@platforms//os:freebsd": "FreeBSD",
92-
# See https://peps.python.org/pep-0730/#platform
93-
# NOTE: Per Pep 730, "iPadOS" is also an acceptable value
94-
"@platforms//os:ios": "iOS",
95-
"@platforms//os:linux": "Linux",
96-
"@platforms//os:netbsd": "NetBSD",
97-
"@platforms//os:openbsd": "OpenBSD",
98-
"@platforms//os:osx": "Darwin",
99-
"@platforms//os:windows": "Windows",
100-
# The value is empty string if it cannot be determined:
101-
# https://docs.python.org/3/library/platform.html#platform.machine
102-
"//conditions:default": "",
103-
}
16+
# Use capitals to hint its not an actual boolean type.
17+
_ENV_MARKER_TRUE = "TRUE"
18+
_ENV_MARKER_FALSE = "FALSE"
10419

10520
def env_marker_setting(*, name, expression, **kwargs):
10621
"""Creates an env_marker setting.
10722
23+
Generated targets:
24+
25+
* `is_{name}_true`: config_setting that matches when the expression is true.
26+
* `{name}`: env marker target that evalutes the expression.
27+
10828
Args:
10929
name: {type}`str` target name
11030
expression: {type}`str` the environment marker string to evaluate
111-
**kwargs: {type}`dict` additionally common kwargs.
31+
**kwargs: {type}`dict` additional common kwargs.
11232
"""
33+
native.config_setting(
34+
name = "is_{}_true".format(name),
35+
flag_values = {
36+
":{}".format(name): _ENV_MARKER_TRUE,
37+
},
38+
**kwargs
39+
)
11340
_env_marker_setting(
11441
name = name,
11542
expression = expression,
116-
os_name = select(_os_name_select_map),
117-
sys_platform = select(_sys_platform_select_map),
118-
platform_machine = select(_platform_machine_select_map),
119-
platform_system = select(_platform_system_select_map),
43+
os_name = select(os_name_select_map),
44+
sys_platform = select(sys_platform_select_map),
45+
platform_machine = select(platform_machine_select_map),
46+
platform_system = select(platform_system_select_map),
12047
**kwargs
12148
)
12249

@@ -149,12 +76,13 @@ def _env_marker_setting_impl(ctx):
14976
env["sys_platform"] = ctx.attr.sys_platform
15077
env["platform_machine"] = ctx.attr.platform_machine
15178

152-
# The `platform_python_implementation` marker value is supposed to come from
153-
# `platform.python_implementation()`, however, PEP 421 introduced
154-
# `sys.implementation.name` to replace it. There's now essentially just two
155-
# possible values it might have: CPython or PyPy. Rather than add a field to
156-
# the toolchain, we just special case the value from
157-
# `sys.implementation.name`
79+
# The `platform_python_implementation` marker value is supposed to come
80+
# from `platform.python_implementation()`, however, PEP 421 introduced
81+
# `sys.implementation.name` and the `implementation_name` env marker to
82+
# replace it. Per the platform.python_implementation docs, there's now
83+
# essentially just two possible "registered" values: CPython or PyPy.
84+
# Rather than add a field to the toolchain, we just special case the value
85+
# from `sys.implementation.name` to handle the two documented values.
15886
platform_python_impl = runtime.implementation_name
15987
if platform_python_impl == "cpython":
16088
platform_python_impl = "CPython"
@@ -170,21 +98,12 @@ def _env_marker_setting_impl(ctx):
17098
env["platform_system"] = ctx.attr.platform_system
17199
env["platform_version"] = _get_flag(ctx.attr._platform_version_config_flag)
172100

173-
# TODO @aignas 2025-04-29: figure out how to correctly share the aliases
174-
# between the two. Maybe the select statements above should be part of the
175-
# `pep508_env.bzl` file?
176-
env = env | {
177-
"_aliases": {
178-
"platform_machine": _platform_machine_aliases,
179-
},
180-
}
101+
env.update(env_aliases())
181102

182103
if evaluate(ctx.attr.expression, env = env):
183-
# todo: better return value than "yes" and "no"
184-
# matched/unmatched, satisfied/unsatisfied ?
185-
value = "yes"
104+
value = _ENV_MARKER_TRUE
186105
else:
187-
value = "no"
106+
value = _ENV_MARKER_FALSE
188107
return [config_common.FeatureFlagInfo(value = value)]
189108

190109
_env_marker_setting = rule(

python/private/pypi/pep508_env.bzl

Lines changed: 92 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
load(":pep508_platform.bzl", "platform_from_str")
1919

2020
# See https://stackoverflow.com/a/45125525
21-
_platform_machine_aliases = {
21+
platform_machine_aliases = {
2222
# These pairs mean the same hardware, but different values may be used
2323
# on different host platforms.
2424
"amd64": "x86_64",
@@ -27,13 +27,66 @@ _platform_machine_aliases = {
2727
"i686": "x86_32",
2828
}
2929

30+
# TODO: there are many cpus and unfortunately, it doesn't look like
31+
# the value is directly accessible to starlark. It might be possible to
32+
# get it via CcToolchain.cpu though.
33+
platform_machine_select_map = {
34+
"@platforms//cpu:aarch32": "aarch32",
35+
"@platforms//cpu:aarch64": "aarch64",
36+
"@platforms//cpu:arm": "arm",
37+
"@platforms//cpu:arm64": "arm64",
38+
"@platforms//cpu:arm64_32": "arm64_32",
39+
"@platforms//cpu:arm64e": "arm64e",
40+
"@platforms//cpu:armv6-m": "armv6-m",
41+
"@platforms//cpu:armv7": "armv7",
42+
"@platforms//cpu:armv7-m": "armv7-m",
43+
"@platforms//cpu:armv7e-m": "armv7e-m",
44+
"@platforms//cpu:armv7e-mf": "armv7e-mf",
45+
"@platforms//cpu:armv7k": "armv7k",
46+
"@platforms//cpu:armv8-m": "armv8-m",
47+
"@platforms//cpu:cortex-r52": "cortex-r52",
48+
"@platforms//cpu:cortex-r82": "cortex-r82",
49+
"@platforms//cpu:i386": "i386",
50+
"@platforms//cpu:mips64": "mips64",
51+
"@platforms//cpu:ppc": "ppc",
52+
"@platforms//cpu:ppc32": "ppc32",
53+
"@platforms//cpu:ppc64le": "ppc64le",
54+
"@platforms//cpu:riscv32": "riscv32",
55+
"@platforms//cpu:riscv64": "riscv64",
56+
"@platforms//cpu:s390x": "s390x",
57+
"@platforms//cpu:wasm32": "wasm32",
58+
"@platforms//cpu:wasm64": "wasm64",
59+
"@platforms//cpu:x86_32": "x86_32",
60+
"@platforms//cpu:x86_64": "x86_64",
61+
# The value is empty string if it cannot be determined:
62+
# https://docs.python.org/3/library/platform.html#platform.machine
63+
"//conditions:default": "",
64+
}
65+
3066
# Platform system returns results from the `uname` call.
3167
_platform_system_values = {
3268
"linux": "Linux",
3369
"osx": "Darwin",
3470
"windows": "Windows",
3571
}
3672

73+
platform_system_select_map = {
74+
# See https://peps.python.org/pep-0738/#platform
75+
"@platforms//os:android": "Android",
76+
"@platforms//os:freebsd": "FreeBSD",
77+
# See https://peps.python.org/pep-0730/#platform
78+
# NOTE: Per Pep 730, "iPadOS" is also an acceptable value
79+
"@platforms//os:ios": "iOS",
80+
"@platforms//os:linux": "Linux",
81+
"@platforms//os:netbsd": "NetBSD",
82+
"@platforms//os:openbsd": "OpenBSD",
83+
"@platforms//os:osx": "Darwin",
84+
"@platforms//os:windows": "Windows",
85+
# The value is empty string if it cannot be determined:
86+
# https://docs.python.org/3/library/platform.html#platform.machine
87+
"//conditions:default": "",
88+
}
89+
3790
# The copy of SO [answer](https://stackoverflow.com/a/13874620) containing
3891
# all of the platforms:
3992
# ┍━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━┑
@@ -64,12 +117,45 @@ _sys_platform_values = {
64117
"osx": "darwin",
65118
"windows": "win32",
66119
}
120+
121+
# Taken from
122+
# https://docs.python.org/3/library/sys.html#sys.platform
123+
sys_platform_select_map = {
124+
# These values are decided by the sys.platform docs.
125+
"@platforms//os:android": "android",
126+
"@platforms//os:emscripten": "emscripten",
127+
"@platforms//os:ios": "ios",
128+
"@platforms//os:linux": "linux",
129+
"@platforms//os:osx": "darwin",
130+
"@platforms//os:windows": "win32",
131+
"@platforms//os:wasi": "wasi",
132+
# NOTE: The below values are approximations. The sys.platform() docs
133+
# don't have documented values for these OSes. Per docs, the
134+
# sys.platform() value reflects the OS at the time Python was *built*
135+
# instead of the runtime (target) OS value.
136+
"@platforms//os:freebsd": "freebsd",
137+
"@platforms//os:openbsd": "openbsd",
138+
# For lack of a better option, use empty string. No standard doc/spec
139+
# about sys_platform value.
140+
"//conditions:default": "",
141+
}
142+
67143
_os_name_values = {
68144
"linux": "posix",
69145
"osx": "posix",
70146
"windows": "nt",
71147
}
72148

149+
os_name_select_map = {
150+
# The "java" value is documented, but with Jython defunct,
151+
# shouldn't occur in practice.
152+
# The os.name value is technically a property of the runtime, not the
153+
# targetted runtime OS, but the distinction shouldn't matter if
154+
# things are properly configured.
155+
"@platforms//os:windows": "nt",
156+
"//conditions:default": "posix",
157+
}
158+
73159
def env(target_platform, *, extra = None):
74160
"""Return an env target platform
75161
@@ -113,8 +199,11 @@ def env(target_platform, *, extra = None):
113199
}
114200

115201
# This is split by topic
116-
return env | {
202+
return env | env_aliases()
203+
204+
def env_aliases():
205+
return {
117206
"_aliases": {
118-
"platform_machine": _platform_machine_aliases,
207+
"platform_machine": platform_machine_aliases,
119208
},
120209
}

tests/pypi/env_marker_setting/env_marker_setting_tests.bzl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@ def _test_expr(name):
2222
cases = {
2323
"python_version_gte": {
2424
"expression": "python_version >= '3.12.0'",
25-
"expected": "yes",
25+
"expected": "TRUE",
2626
"config_settings": {
2727
PYTHON_VERSION: "3.12.0",
2828
},
2929
},
3030
"python_full_version_lt_negative": {
3131
"expression": "python_full_version < '3.8'",
32-
"expected": "no",
32+
"expected": "FALSE",
3333
"config_settings": {
3434
PYTHON_VERSION: "3.12.0",
3535
},

0 commit comments

Comments
 (0)