1515"""This module is for implementing PEP508 environment definition.
1616"""
1717
18+ load ("//python/private:version.bzl" , "version" )
19+
20+ _DEFAULT = "//conditions:default"
21+
22+ # Here we store the aliases in the platform so that the users can specify any valid target in
23+ # there.
24+ _cpu_aliases = {
25+ "arm" : "aarch32" ,
26+ "arm64" : "aarch64" ,
27+ }
28+ _os_aliases = {
29+ "macos" : "osx" ,
30+ }
31+
1832# See https://stackoverflow.com/a/45125525
1933platform_machine_aliases = {
20- # These pairs mean the same hardware, but different values may be used
21- # on different host platforms.
34+ # These pairs mean the same hardware, but different values may be used on different host
35+ # platforms.
36+ #
37+ # What is more we ensure in this way that we have all of the values from the platforms
38+ # package when constructing the env.
2239 "amd64" : "x86_64" ,
2340 "arm64" : "aarch64" ,
2441 "i386" : "x86_32" ,
@@ -32,6 +49,7 @@ platform_machine_aliases = {
3249platform_machine_select_map = {
3350 "@platforms//cpu:aarch32" : "aarch32" ,
3451 "@platforms//cpu:aarch64" : "aarch64" ,
52+ # We store them above
3553 # @platforms//cpu:arm is an alias for @platforms//cpu:aarch32
3654 # @platforms//cpu:arm64 is an alias for @platforms//cpu:aarch64
3755 "@platforms//cpu:arm64_32" : "arm64_32" ,
@@ -59,31 +77,25 @@ platform_machine_select_map = {
5977 "@platforms//cpu:x86_64" : "x86_64" ,
6078 # The value is empty string if it cannot be determined:
6179 # https://docs.python.org/3/library/platform.html#platform.machine
62- "//conditions:default" : "" ,
80+ _DEFAULT : "" ,
6381}
6482
6583# Platform system returns results from the `uname` call.
66- _platform_system_values = {
84+ platform_system_select_map = {
6785 # See https://peps.python.org/pep-0738/#platform
68- "android" : "Android" ,
69- "freebsd" : "FreeBSD" ,
86+ "@platforms//os: android" : "Android" ,
87+ "@platforms//os: freebsd" : "FreeBSD" ,
7088 # See https://peps.python.org/pep-0730/#platform
7189 # NOTE: Per Pep 730, "iPadOS" is also an acceptable value
72- "ios" : "iOS" ,
73- "linux" : "Linux" ,
74- "netbsd" : "NetBSD" ,
75- "openbsd" : "OpenBSD" ,
76- "osx" : "Darwin" ,
77- "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- } | {
90+ "@platforms//os:ios" : "iOS" ,
91+ "@platforms//os:linux" : "Linux" ,
92+ "@platforms//os:netbsd" : "NetBSD" ,
93+ "@platforms//os:openbsd" : "OpenBSD" ,
94+ "@platforms//os:osx" : "Darwin" ,
95+ "@platforms//os:windows" : "Windows" ,
8496 # The value is empty string if it cannot be determined:
8597 # https://docs.python.org/3/library/platform.html#platform.machine
86- "//conditions:default" : "" ,
98+ _DEFAULT : "" ,
8799}
88100
89101# The copy of SO [answer](https://stackoverflow.com/a/13874620) containing
@@ -111,83 +123,83 @@ platform_system_select_map = {
111123# (**) Prior Python 3.8 could also be aix5 or aix7; use sys.platform.startswith()
112124#
113125# We are using only the subset that we actually support.
114- _sys_platform_values = {
126+ sys_platform_select_map = {
115127 # These values are decided by the sys.platform docs.
116- "android" : "android" ,
117- "emscripten" : "emscripten" ,
128+ "@platforms//os: android" : "android" ,
129+ "@platforms//os: emscripten" : "emscripten" ,
118130 # NOTE: The below values are approximations. The sys.platform() docs
119131 # don't have documented values for these OSes. Per docs, the
120132 # sys.platform() value reflects the OS at the time Python was *built*
121133 # 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- } | {
134+ "@platforms//os:freebsd" : "freebsd" ,
135+ "@platforms//os:ios" : "ios" ,
136+ "@platforms//os:linux" : "linux" ,
137+ "@platforms//os:openbsd" : "openbsd" ,
138+ # @platforms//os:macos is an alias for @platforms//os:osx
139+ "@platforms//os:osx" : "darwin" ,
140+ "@platforms//os:wasi" : "wasi" ,
141+ "@platforms//os:windows" : "win32" ,
135142 # For lack of a better option, use empty string. No standard doc/spec
136143 # about sys_platform value.
137- "//conditions:default" : "" ,
144+ _DEFAULT : "" ,
138145}
139146
140147# The "java" value is documented, but with Jython defunct,
141148# shouldn't occur in practice.
142149# The os.name value is technically a property of the runtime, not the
143150# targetted runtime OS, but the distinction shouldn't matter if
144151# things are properly configured.
145- _os_name_values = {
146- "linux" : "posix" ,
147- "osx" : "posix" ,
148- "windows" : "nt" ,
149- }
150-
151152os_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" ,
153+ "@platforms//os:windows" : "nt" ,
154+ _DEFAULT : "posix" ,
156155}
157156
158- def env (target_platform , * , extra = None ):
157+ def _get_from_map (m , key ):
158+ if _DEFAULT in m :
159+ return m .get (key , m [_DEFAULT ])
160+ else :
161+ return m [key ]
162+
163+ def env (* , env = None , os , arch , python_version = "" , extra = None ):
159164 """Return an env target platform
160165
161166 NOTE: This is for use during the loading phase. For the analysis phase,
162167 `env_marker_setting()` constructs the env dict.
163168
164169 Args:
165- target_platform: {type}`str` the target platform identifier, e.g.
166- `cp33_linux_aarch64`
170+ env: {type}`str` the environment.
171+ os: {type}`str` the OS name.
172+ arch: {type}`str` the CPU name.
173+ python_version: {type}`str` the full python version.
167174 extra: {type}`str` the extra value to be added into the env.
168175
169176 Returns:
170177 A dict that can be used as `env` in the marker evaluation.
171178 """
172- env = create_env ()
179+ env = env or {}
180+ env = env | create_env ()
173181 if extra != None :
174182 env ["extra" ] = extra
175183
176- if target_platform .abi :
177- minor_version , _ , micro_version = target_platform .abi [3 :].partition ("." )
178- micro_version = micro_version or "0"
184+ if python_version :
185+ v = version .parse (python_version )
186+ major = v .release [0 ]
187+ minor = v .release [1 ]
188+ micro = v .release [2 ] if len (v .release ) > 2 else 0
179189 env = env | {
180- "implementation_version" : "3 .{}.{}" .format (minor_version , micro_version ),
181- "python_full_version" : "3 .{}.{}" .format (minor_version , micro_version ),
182- "python_version" : "3 .{}" .format (minor_version ),
190+ "implementation_version" : "{} .{}.{}" .format (major , minor , micro ),
191+ "python_full_version" : "{} .{}.{}" .format (major , minor , micro ),
192+ "python_version" : "{} .{}" .format (major , minor ),
183193 }
184- if target_platform .os and target_platform .arch :
185- os = target_platform .os
194+
195+ if os and arch :
196+ os = "@platforms//os:{}" .format (_os_aliases .get (os , os ))
197+ arch = "@platforms//cpu:{}" .format (_cpu_aliases .get (arch , arch ))
186198 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 , "" ),
199+ "os_name" : _get_from_map ( os_name_select_map , os ),
200+ "platform_machine" : _get_from_map ( platform_machine_select_map , arch ) ,
201+ "platform_system" : _get_from_map ( platform_system_select_map , os ),
202+ "sys_platform" : _get_from_map ( sys_platform_select_map , os ),
191203 }
192204 set_missing_env_defaults (env )
193205
0 commit comments