@@ -28,18 +28,22 @@ _platform_machine_aliases = {
2828# Taken from
2929# https://docs.python.org/3/library/sys.html#sys.platform
3030_sys_platform_select_map = {
31+ # These values are decided by the sys.platform docs.
3132 "@platforms//os:android" : "android" ,
3233 "@platforms//os:emscripten" : "emscripten" ,
33- # NOTE, the below values here are from the time when the Python
34- # interpreter is built and it is hard to know for sure, maybe this
35- # should be something from the toolchain?
36- "@platforms//os:freebsd" : "freebsd8" ,
3734 "@platforms//os:ios" : "ios" ,
3835 "@platforms//os:linux" : "linux" ,
39- "@platforms//os:openbsd" : "openbsd6" ,
4036 "@platforms//os:osx" : "darwin" ,
41- "@platforms//os:wasi" : "wasi" ,
4237 "@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.
4347 "//conditions:default" : "" ,
4448}
4549
@@ -86,7 +90,8 @@ _platform_system_select_map = {
8690 "@platforms//os:android" : "Android" ,
8791 "@platforms//os:freebsd" : "FreeBSD" ,
8892 # See https://peps.python.org/pep-0730/#platform
89- "@platforms//os:ios" : "iOS" , # can also be iPadOS?
93+ # NOTE: Per Pep 730, "iPadOS" is also an acceptable value
94+ "@platforms//os:ios" : "iOS" ,
9095 "@platforms//os:linux" : "Linux" ,
9196 "@platforms//os:netbsd" : "NetBSD" ,
9297 "@platforms//os:openbsd" : "OpenBSD" ,
@@ -108,7 +113,7 @@ def env_marker_setting(**kwargs):
108113
109114# todo: maybe put all the env into a single target and have a
110115# PyPiEnvMarkersInfo provider? Have --pypi_env=//some:target?
111- def _impl (ctx ):
116+ def _env_marker_setting_impl (ctx ):
112117 # todo: should unify with pep508_env.bzl
113118 env = {}
114119
@@ -119,11 +124,11 @@ def _impl(ctx):
119124 major = version_info .major ,
120125 minor = version_info .minor ,
121126 )
122- full_version = format_full_version (version_info )
127+ full_version = _format_full_version (version_info )
123128 env ["python_full_version" ] = full_version
124129 env ["implementation_version" ] = full_version
125130 else :
126- env ["python_version" ] = _get_flag (ctx .attr ._python_version )
131+ env ["python_version" ] = _get_flag (ctx .attr ._python_version_major_minor_flag )
127132 full_version = _get_flag (ctx .attr ._python_full_version )
128133 env ["python_full_version" ] = full_version
129134 env ["implementation_version" ] = full_version
@@ -135,23 +140,26 @@ def _impl(ctx):
135140 env ["sys_platform" ] = ctx .attr .sys_platform
136141 env ["platform_machine" ] = ctx .attr .platform_machine
137142
138- # todo: maybe add PyRuntimeInfo.platform_python_implementation?
139- # The values are slightly different to implementation_name.
140- # However, digging through old PEPs, it looks like
141- # platform.python_implementation is legacy, and sys.implementation.name
142- # "replaced" it. Can probably just special case this.
143+ # The `platform_python_implementation` marker value is supposed to come from
144+ # `platform.python_implementation()`, however, PEP 421 introduced
145+ # `sys.implementation.name` to replace it. There's now essentially just two
146+ # possible values it might have: CPython or PyPy. Rather than add a field to
147+ # the toolchain, we just special case the value from
148+ # `sys.implementation.name`
143149 platform_python_impl = runtime .implementation_name
144150 if platform_python_impl == "cpython" :
145151 platform_python_impl = "CPython"
152+ elif platform_python_impl == "pypy" :
153+ platform_python_impl = "PyPy"
146154 env ["platform_python_implementation" ] = platform_python_impl
147155
148156 # NOTE: Platform release for Android will be Android version:
149157 # https://peps.python.org/pep-0738/#platform
150158 # Similar for iOS:
151159 # https://peps.python.org/pep-0730/#platform
152- env ["platform_release" ] = ctx .attr ._platform_release_config_flag [ BuildSettingInfo ]. value
160+ env ["platform_release" ] = _get_flag ( ctx .attr ._platform_release_config_flag )
153161 env ["platform_system" ] = ctx .attr .platform_system
154- env ["platform_version" ] = ctx .attr ._platform_version_config_flag [ BuildSettingInfo ]. value
162+ env ["platform_version" ] = _get_flag ( ctx .attr ._platform_version_config_flag )
155163
156164 # TODO @aignas 2025-04-29: figure out how to correctly share the aliases
157165 # between the two. Maybe the select statements above should be part of the
@@ -171,34 +179,34 @@ def _impl(ctx):
171179 return [config_common .FeatureFlagInfo (value = value )]
172180
173181_env_marker_setting = rule (
174- implementation = _impl ,
182+ doc = """
183+ Config setting to evaluate a PyPA environment marker expression.
184+ """ ,
185+ implementation = _env_marker_setting_impl ,
175186 attrs = {
176- "expression" : attr .string (),
187+ "expression" : attr .string (
188+ mandatory = True ,
189+ doc = "Environment marker expression to evaluate." ,
190+ ),
177191 "os_name" : attr .string (),
178192 "platform_machine" : attr .string (),
179193 "platform_system" : attr .string (),
180194 "sys_platform" : attr .string (),
181- # todo: what to do with this?
182- # NOTE(aignas) - with the `evaluate` function we can evaluate a
183- # particular value. For example we can have an expression and just
184- # evaluate extras. I.e. if the extras don't match, then the whole thing
185- # is false, if it matches, then it is a string with a remaining
186- # expression. This means that the `pypa_dependency_specification`
187- # should not receive any `extra_flags` because these are not properties
188- # of the target configuration, but rather of a particular package,
189- # hence we could drop it.
190- "_extra_flag" : attr .label (),
191195 "_platform_release_config_flag" : attr .label (
192196 default = "//python/config_settings:pip_platform_release_config" ,
197+ providers = [[config_common .FeatureFlagInfo ], [BuildSettingInfo ]],
193198 ),
194199 "_platform_version_config_flag" : attr .label (
195200 default = "//python/config_settings:pip_platform_version_config" ,
201+ providers = [[config_common .FeatureFlagInfo ], [BuildSettingInfo ]],
196202 ),
197203 "_python_full_version_flag" : attr .label (
198204 default = "//python/config_settings:python_version" ,
205+ providers = [config_common .FeatureFlagInfo ],
199206 ),
200- "_python_version_flag " : attr .label (
207+ "_python_version_major_minor_flag " : attr .label (
201208 default = "//python/config_settings:python_version_major_minor" ,
209+ providers = [config_common .FeatureFlagInfo ],
202210 ),
203211 },
204212 provides = [config_common .FeatureFlagInfo ],
@@ -207,7 +215,7 @@ _env_marker_setting = rule(
207215 ],
208216)
209217
210- def format_full_version (info ):
218+ def _format_full_version (info ):
211219 """Format the full python interpreter version.
212220
213221 Adapted from spec code at:
0 commit comments