From 51f10470a906611979c5e62c92aa08648980bc94 Mon Sep 17 00:00:00 2001 From: Ignas Anikevicius <240938+aignas@users.noreply.github.com> Date: Sun, 12 Jan 2025 22:15:02 +0900 Subject: [PATCH] refactor(pypi): rename config settings and improve docs (#2556) Before the PR the `config_setting` names where following an internal logic and those names would be leaking into the error messages when no match is found. I thought that the names thus should be improved and maybe made more similar to the `whl` filename parts that they are derived from. As part of this change I have also added more docs and added them to sphinxdocs in the hopes that this documentation helps maintainers and users looking at error messages alike. Summary: * Make names more similar to the whl filenames. * Instead of having `osx__universal2` config settings for each `cpu` value, have a single `osx_universal2` config setting. * Stop creating redundant/unused config settings * Refactor the `_dist_config_setting` code to be simpler and create fewer targets by using a clever trick for the `whl` config setting flag value usage. The stats: ``` $ bazel query //tests/pypi/config_settings/... | rg ":(|_)is" | wc -l 2223 $ bazel query @dev_pip//_config/... | wc -l 1982 $ bazel query //tests/pypi/config_settings/... | rg ":(|_)is" | wc -l 1780 $ bazel query @dev_pip//_config/... | wc -l 1066 ``` Work towards #260 --- docs/BUILD.bazel | 2 + python/private/pypi/BUILD.bazel | 61 ++-- python/private/pypi/config_settings.bzl | 261 ++++++++---------- python/private/pypi/flags.bzl | 37 ++- python/private/pypi/pkg_aliases.bzl | 129 ++++++--- python/private/pypi/render_pkg_aliases.bzl | 2 +- .../config_settings/config_settings_tests.bzl | 214 +++++++++----- tests/pypi/pkg_aliases/pkg_aliases_test.bzl | 44 +-- .../render_pkg_aliases_test.bzl | 44 ++- 9 files changed, 474 insertions(+), 320 deletions(-) diff --git a/docs/BUILD.bazel b/docs/BUILD.bazel index a9a1db02a8..e365532d01 100644 --- a/docs/BUILD.bazel +++ b/docs/BUILD.bazel @@ -103,6 +103,8 @@ sphinx_stardocs( "//python/private:py_runtime_rule_bzl", "//python/private:py_test_rule_bzl", "//python/private/api:py_common_api_bzl", + "//python/private/pypi:config_settings_bzl", + "//python/private/pypi:pkg_aliases_bzl", ] + ([ # Bazel 6 + Stardoc isn't able to parse something about the python bzlmod extension "//python/extensions:python_bzl", diff --git a/python/private/pypi/BUILD.bazel b/python/private/pypi/BUILD.bazel index 7e2d398fde..6f80272af6 100644 --- a/python/private/pypi/BUILD.bazel +++ b/python/private/pypi/BUILD.bazel @@ -53,6 +53,32 @@ bzl_library( srcs = ["attrs.bzl"], ) +bzl_library( + name = "config_settings_bzl", + srcs = ["config_settings.bzl"], + deps = [ + ":flags_bzl", + "//python/private:flags_bzl", + ], +) + +bzl_library( + name = "deps_bzl", + srcs = ["deps.bzl"], + deps = [ + "//python/private:bazel_tools_bzl", + "//python/private:glob_excludes_bzl", + ], +) + +bzl_library( + name = "evaluate_markers_bzl", + srcs = ["evaluate_markers.bzl"], + deps = [ + ":pypi_repo_utils_bzl", + ], +) + bzl_library( name = "extension_bzl", srcs = ["extension.bzl"], @@ -76,29 +102,6 @@ bzl_library( ], ) -bzl_library( - name = "config_settings_bzl", - srcs = ["config_settings.bzl"], - deps = ["flags_bzl"], -) - -bzl_library( - name = "deps_bzl", - srcs = ["deps.bzl"], - deps = [ - "//python/private:bazel_tools_bzl", - "//python/private:glob_excludes_bzl", - ], -) - -bzl_library( - name = "evaluate_markers_bzl", - srcs = ["evaluate_markers.bzl"], - deps = [ - ":pypi_repo_utils_bzl", - ], -) - bzl_library( name = "flags_bzl", srcs = ["flags.bzl"], @@ -245,6 +248,18 @@ bzl_library( srcs = ["pip_repository_attrs.bzl"], ) +bzl_library( + name = "pkg_aliases_bzl", + srcs = ["pkg_aliases.bzl"], + deps = [ + ":labels_bzl", + ":parse_whl_name_bzl", + ":whl_target_platforms_bzl", + "//python/private:text_util_bzl", + "@bazel_skylib//lib:selects", + ], +) + bzl_library( name = "pypi_repo_utils_bzl", srcs = ["pypi_repo_utils.bzl"], diff --git a/python/private/pypi/config_settings.bzl b/python/private/pypi/config_settings.bzl index 620e50e997..1045ffef35 100644 --- a/python/private/pypi/config_settings.bzl +++ b/python/private/pypi/config_settings.bzl @@ -13,31 +13,59 @@ # limitations under the License. """ -This module is used to construct the config settings for selecting which distribution is used in the pip hub repository. +The {obj}`config_settings` macro is used to create the config setting targets +that can be used in the {obj}`pkg_aliases` macro for selecting the compatible +repositories. Bazel's selects work by selecting the most-specialized configuration setting -that matches the target platform. We can leverage this fact to ensure that the -most specialized wheels are used by default with the users being able to -configure string_flag values to select the less specialized ones. - -The list of specialization of the dists goes like follows (cpxyt stands for freethreaded -environments): -* sdist -* py*-none-any.whl -* py*-abi3-any.whl -* py*-cpxy-any.whl or py*-cpxyt-any.whl -* cp*-none-any.whl -* cp*-abi3-any.whl -* cp*-cpxy-any.whl or cp*-cpxyt-any.whl -* py*-none-plat.whl -* py*-abi3-plat.whl -* py*-cpxy-plat.whl or py*-cpxyt-plat.whl -* cp*-none-plat.whl -* cp*-abi3-plat.whl -* cp*-cpxy-plat.whl or cp*-cpxyt-plat.whl - -Note, that here the specialization of musl vs manylinux wheels is the same in -order to ensure that the matching fails if the user requests for `musl` and we don't have it or vice versa. +that matches the target platform, which is further described in [bazel documentation][docs]. +We can leverage this fact to ensure that the most specialized matches are used +by default with the users being able to configure string_flag values to select +the less specialized ones. + +[docs]: https://bazel.build/docs/configurable-attributes + +The config settings in the order from the least specialized to the most +specialized is as follows: +* `:is_cp3` +* `:is_cp3_sdist` +* `:is_cp3_py_none_any` +* `:is_cp3_py3_none_any` +* `:is_cp3_py3_abi3_any` +* `:is_cp3_none_any` +* `:is_cp3_any_any` +* `:is_cp3_cp3_any` and `:is_cp3_cp3t_any` +* `:is_cp3_py_none_` +* `:is_cp3_py3_none_` +* `:is_cp3_py3_abi3_` +* `:is_cp3_none_` +* `:is_cp3_abi3_` +* `:is_cp3_cp3_` and `:is_cp3_cp3t_` + +The specialization of free-threaded vs non-free-threaded wheels is the same as +they are just variants of each other. The same goes for the specialization of +`musllinux` vs `manylinux`. + +The goal of this macro is to provide config settings that provide unambigous +matches if any pair of them is used together for any target configuration +setting. We achieve this by using dummy internal `flag_values` keys to force the +items further down the list to appear to be more specialized than the ones above. + +What is more, the names of the config settings are as similar to the platform wheel +specification as possible. How the wheel names map to the config setting names defined +in here is described in {obj}`pkg_aliases` documentation. + +:::{note} +Right now the specialization of adjacent config settings where one is with +`constraint_values` and one is without is ambiguous. I.e. `py_none_any` and +`sdist_linux_x86_64` have the same specialization from bazel point of view +because one has one `flag_value` entry and `constraint_values` and the +other has 2 flag_value entries. And unfortunately there is no way to disambiguate +it, because we are essentially in two dimensions here (`flag_values` and +`constraint_values`). Hence, when using the `config_settings` from here, +either have all of them with empty `suffix` or all of them with a non-empty +suffix. +::: """ load("//python/private:flags.bzl", "LibcFlag") @@ -83,8 +111,7 @@ def config_settings( osx_versions = [], target_platforms = [], name = None, - visibility = None, - native = native): + **kwargs): """Generate all of the pip config settings. Args: @@ -99,35 +126,19 @@ def config_settings( config settings for. target_platforms (list[str]): The list of "{os}_{cpu}" for deriving constraint values for each condition. - visibility (list[str], optional): The visibility to be passed to the - exposed labels. All other labels will be private. - native (struct): The struct containing alias and config_setting rules - to use for creating the objects. Can be overridden for unit tests - reasons. + **kwargs: Other args passed to the underlying implementations, such as + {obj}`native`. """ glibc_versions = [""] + glibc_versions muslc_versions = [""] + muslc_versions osx_versions = [""] + osx_versions - target_platforms = [("", "")] + [ + target_platforms = [("", ""), ("osx", "universal2")] + [ t.split("_", 1) for t in target_platforms ] - for python_version in [""] + python_versions: - is_python = "is_python_{}".format(python_version or "version_unset") - - # The aliases defined in @rules_python//python/config_settings may not - # have config settings for the versions we need, so define our own - # config settings instead. - native.config_setting( - name = is_python, - flag_values = { - Label("//python/config_settings:python_version_major_minor"): python_version, - }, - visibility = visibility, - ) - + for python_version in python_versions: for os, cpu in target_platforms: constraint_values = [] suffix = "" @@ -135,8 +146,9 @@ def config_settings( constraint_values.append("@platforms//os:" + os) suffix += "_" + os if cpu: - constraint_values.append("@platforms//cpu:" + cpu) suffix += "_" + cpu + if cpu != "universal2": + constraint_values.append("@platforms//cpu:" + cpu) _dist_config_settings( suffix = suffix, @@ -149,20 +161,24 @@ def config_settings( ), constraint_values = constraint_values, python_version = python_version, - is_python = is_python, - visibility = visibility, - native = native, + **kwargs ) -def _dist_config_settings(*, suffix, plat_flag_values, **kwargs): - if kwargs.get("constraint_values"): - # Add python version + platform config settings - _dist_config_setting( - name = suffix.strip("_"), - **kwargs - ) +def _dist_config_settings(*, suffix, plat_flag_values, python_version, **kwargs): + flag_values = { + Label("//python/config_settings:python_version_major_minor"): python_version, + } - flag_values = {_flags.dist: ""} + cpv = "cp" + python_version.replace(".", "") + prefix = "is_{}".format(cpv) + + _dist_config_setting( + name = prefix + suffix, + flag_values = flag_values, + **kwargs + ) + + flag_values[_flags.dist] = "" # First create an sdist, we will be building upon the flag values, which # will ensure that each sdist config setting is the least specialized of @@ -170,9 +186,9 @@ def _dist_config_settings(*, suffix, plat_flag_values, **kwargs): # have `sdist` for any platform, hence we have a non-empty `flag_values` # here. _dist_config_setting( - name = "sdist{}".format(suffix), + name = "{}_sdist{}".format(prefix, suffix), flag_values = flag_values, - is_pip_whl = FLAGS.is_pip_whl_no, + compatible_with = (FLAGS.is_pip_whl_no, FLAGS.is_pip_whl_auto), **kwargs ) @@ -184,29 +200,28 @@ def _dist_config_settings(*, suffix, plat_flag_values, **kwargs): # The discussion here also reinforces this notion: # https://discuss.python.org/t/pep-703-making-the-global-interpreter-lock-optional-3-12-updates/26503/99 - for name, f, abi in [ - ("py_none", _flags.whl_py2_py3, None), + for name, f, compatible_with in [ + ("py_none", _flags.whl, None), ("py3_none", _flags.whl_py3, None), ("py3_abi3", _flags.whl_py3_abi3, (FLAGS.is_py_non_freethreaded,)), - ("cp3x_none", _flags.whl_pycp3x, None), - ("cp3x_abi3", _flags.whl_pycp3x_abi3, (FLAGS.is_py_non_freethreaded,)), + ("none", _flags.whl_pycp3x, None), + ("abi3", _flags.whl_pycp3x_abi3, (FLAGS.is_py_non_freethreaded,)), # The below are not specializations of one another, they are variants - ("cp3x_cp", _flags.whl_pycp3x_abicp, (FLAGS.is_py_non_freethreaded,)), - ("cp3x_cpt", _flags.whl_pycp3x_abicp, (FLAGS.is_py_freethreaded,)), + (cpv, _flags.whl_pycp3x_abicp, (FLAGS.is_py_non_freethreaded,)), + (cpv + "t", _flags.whl_pycp3x_abicp, (FLAGS.is_py_freethreaded,)), ]: - if (f, abi) in used_flags: + if (f, compatible_with) in used_flags: # This should never happen as all of the different whls should have # unique flag values fail("BUG: the flag {} is attempted to be added twice to the list".format(f)) else: - flag_values[f] = "" - used_flags[(f, abi)] = True + flag_values[f] = "yes" if f == _flags.whl else "" + used_flags[(f, compatible_with)] = True _dist_config_setting( - name = "{}_any{}".format(name, suffix), + name = "{}_{}_any{}".format(prefix, name, suffix), flag_values = flag_values, - is_pip_whl = FLAGS.is_pip_whl_only, - abi = abi, + compatible_with = compatible_with, **kwargs ) @@ -217,29 +232,28 @@ def _dist_config_settings(*, suffix, plat_flag_values, **kwargs): used_flags = {(f, None): True for f in flag_values} | generic_used_flags flag_values = flag_values | generic_flag_values - for name, f, abi in [ + for name, f, compatible_with in [ ("py_none", _flags.whl_plat, None), ("py3_none", _flags.whl_plat_py3, None), ("py3_abi3", _flags.whl_plat_py3_abi3, (FLAGS.is_py_non_freethreaded,)), - ("cp3x_none", _flags.whl_plat_pycp3x, None), - ("cp3x_abi3", _flags.whl_plat_pycp3x_abi3, (FLAGS.is_py_non_freethreaded,)), + ("none", _flags.whl_plat_pycp3x, None), + ("abi3", _flags.whl_plat_pycp3x_abi3, (FLAGS.is_py_non_freethreaded,)), # The below are not specializations of one another, they are variants - ("cp3x_cp", _flags.whl_plat_pycp3x_abicp, (FLAGS.is_py_non_freethreaded,)), - ("cp3x_cpt", _flags.whl_plat_pycp3x_abicp, (FLAGS.is_py_freethreaded,)), + (cpv, _flags.whl_plat_pycp3x_abicp, (FLAGS.is_py_non_freethreaded,)), + (cpv + "t", _flags.whl_plat_pycp3x_abicp, (FLAGS.is_py_freethreaded,)), ]: - if (f, abi) in used_flags: + if (f, compatible_with) in used_flags: # This should never happen as all of the different whls should have # unique flag values. fail("BUG: the flag {} is attempted to be added twice to the list".format(f)) else: flag_values[f] = "" - used_flags[(f, abi)] = True + used_flags[(f, compatible_with)] = True _dist_config_setting( - name = "{}_{}".format(name, suffix), + name = "{}_{}_{}".format(prefix, name, suffix), flag_values = flag_values, - is_pip_whl = FLAGS.is_pip_whl_only, - abi = abi, + compatible_with = compatible_with, **kwargs ) @@ -256,23 +270,19 @@ def _plat_flag_values(os, cpu, osx_versions, glibc_versions, muslc_versions): elif os == "windows": ret.append(("{}_{}".format(os, cpu), {})) elif os == "osx": - for cpu_, arch in { - cpu: UniversalWhlFlag.ARCH, - cpu + "_universal2": UniversalWhlFlag.UNIVERSAL, - }.items(): - for osx_version in osx_versions: - flags = { - FLAGS.pip_whl_osx_version: _to_version_string(osx_version), - } - if arch == UniversalWhlFlag.ARCH: - flags[FLAGS.pip_whl_osx_arch] = arch - - if not osx_version: - suffix = "{}_{}".format(os, cpu_) - else: - suffix = "{}_{}_{}".format(os, _to_version_string(osx_version, "_"), cpu_) + for osx_version in osx_versions: + flags = { + FLAGS.pip_whl_osx_version: _to_version_string(osx_version), + } + if cpu != "universal2": + flags[FLAGS.pip_whl_osx_arch] = UniversalWhlFlag.ARCH + + if not osx_version: + suffix = "{}_{}".format(os, cpu) + else: + suffix = "{}_{}_{}".format(os, _to_version_string(osx_version, "_"), cpu) - ret.append((suffix, flags)) + ret.append((suffix, flags)) elif os == "linux": for os_prefix, linux_libc in { @@ -309,16 +319,12 @@ def _plat_flag_values(os, cpu, osx_versions, glibc_versions, muslc_versions): return ret -def _dist_config_setting(*, name, is_python, python_version, is_pip_whl = None, abi = None, native = native, **kwargs): - """A macro to create a target that matches is_pip_whl_auto and one more value. +def _dist_config_setting(*, name, compatible_with = None, native = native, **kwargs): + """A macro to create a target for matching Python binary and source distributions. Args: name: The name of the public target. - is_pip_whl: The config setting to match in addition to - `is_pip_whl_auto` when evaluating the config setting. - is_python: The python version config_setting to match. - python_version: The python version name. - abi: {type}`tuple[Label]` A collection of ABI config settings that are + compatible_with: {type}`tuple[Label]` A collection of config settings that are compatible with the given dist config setting. For example, if only non-freethreaded python builds are allowed, add FLAGS.is_py_non_freethreaded here. @@ -328,50 +334,17 @@ def _dist_config_setting(*, name, is_python, python_version, is_pip_whl = None, **kwargs: The kwargs passed to the config_setting rule. Visibility of the main alias target is also taken from the kwargs. """ - _name = "_is_" + name - - visibility = kwargs.get("visibility") - native.alias( - name = "is_cp{}_{}".format(python_version, name) if python_version else "is_{}".format(name), - actual = select({ - # First match by the python version and then by ABI - is_python: _name + ("_abi" if abi else ""), - _DEFAULT: _INCOMPATIBLE, - }), - visibility = visibility, - ) - - if python_version: - # Reuse the config_setting targets that we use with the default - # `python_version` setting. - return - - if not is_pip_whl: - native.config_setting(name = _name, **kwargs) - return - - config_setting_name = _name + "_setting" - native.config_setting(name = config_setting_name, **kwargs) - - if abi: + if compatible_with: + dist_config_setting_name = "_" + name native.alias( - name = _name + "_abi", + name = name, actual = select( - {k: _name for k in abi} | { + {setting: dist_config_setting_name for setting in compatible_with} | { _DEFAULT: _INCOMPATIBLE, }, ), - visibility = visibility, + visibility = kwargs.get("visibility"), ) + name = dist_config_setting_name - # Next match by the `pip_whl` flag value and then match by the flags that - # are intrinsic to the distribution. - native.alias( - name = _name, - actual = select({ - _DEFAULT: _INCOMPATIBLE, - FLAGS.is_pip_whl_auto: config_setting_name, - is_pip_whl: config_setting_name, - }), - visibility = visibility, - ) + native.config_setting(name = name, **kwargs) diff --git a/python/private/pypi/flags.bzl b/python/private/pypi/flags.bzl index 11727b5853..a25579a2b8 100644 --- a/python/private/pypi/flags.bzl +++ b/python/private/pypi/flags.bzl @@ -18,7 +18,7 @@ NOTE: The transitive loads of this should be kept minimal. This avoids loading unnecessary files when all that are needed are flag definitions. """ -load("@bazel_skylib//rules:common_settings.bzl", "string_flag") +load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo", "string_flag") load("//python/private:enum.bzl", "enum") # Determines if we should use whls for third party @@ -44,7 +44,7 @@ UniversalWhlFlag = enum( UNIVERSAL = "universal", ) -INTERNAL_FLAGS = [ +_STRING_FLAGS = [ "dist", "whl_plat", "whl_plat_py3", @@ -52,7 +52,6 @@ INTERNAL_FLAGS = [ "whl_plat_pycp3x", "whl_plat_pycp3x_abi3", "whl_plat_pycp3x_abicp", - "whl_py2_py3", "whl_py3", "whl_py3_abi3", "whl_pycp3x", @@ -60,11 +59,41 @@ INTERNAL_FLAGS = [ "whl_pycp3x_abicp", ] +INTERNAL_FLAGS = [ + "whl", +] + _STRING_FLAGS + def define_pypi_internal_flags(name): - for flag in INTERNAL_FLAGS: + """define internal PyPI flags used in PyPI hub repository by pkg_aliases. + + Args: + name: not used + """ + for flag in _STRING_FLAGS: string_flag( name = "_internal_pip_" + flag, build_setting_default = "", values = [""], visibility = ["//visibility:public"], ) + + _allow_wheels_flag( + name = "_internal_pip_whl", + visibility = ["//visibility:public"], + ) + +def _allow_wheels_flag_impl(ctx): + input = ctx.attr._setting[BuildSettingInfo].value + value = "yes" if input in ["auto", "only"] else "no" + return [config_common.FeatureFlagInfo(value = value)] + +_allow_wheels_flag = rule( + implementation = _allow_wheels_flag_impl, + attrs = { + "_setting": attr.label(default = "//python/config_settings:pip_whl"), + }, + doc = """\ +This rule allows us to greatly reduce the number of config setting targets at no cost even +if we are duplicating some of the functionality of the `native.config_setting`. +""", +) diff --git a/python/private/pypi/pkg_aliases.bzl b/python/private/pypi/pkg_aliases.bzl index 980921b474..a9eee7be88 100644 --- a/python/private/pypi/pkg_aliases.bzl +++ b/python/private/pypi/pkg_aliases.bzl @@ -12,9 +12,66 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""pkg_aliases is a macro to generate aliases for selecting the right wheel for the right target platform. - -This is used in bzlmod and non-bzlmod setups.""" +"""{obj}`pkg_aliases` is a macro to generate aliases for selecting the right wheel for the right target platform. + +If you see an error where the distribution selection error indicates the config setting names this +page may help to describe the naming convention and relationship between various flags and options +in `rules_python` and the error message contents. + +Definitions: +:minor_version: Python interpreter minor version that the distributions are compatible with. +:suffix: Can be either empty or `__`, which is usually used to distinguish multiple versions used for different target platforms. +:os: OS identifier that exists in `@platforms//os:`. +:cpu: CPU architecture identifier that exists in `@platforms//cpu:`. +:python_tag: The Python tag as defined by the [Python Packaging Authority][packaging_spec]. E.g. `py2.py3`, `py3`, `py311`, `cp311`. +:abi_tag: The ABI tag as defined by the [Python Packaging Authority][packaging_spec]. E.g. `none`, `abi3`, `cp311`, `cp311t`. +:platform_tag: The Platform tag as defined by the [Python Packaging Authority][packaging_spec]. E.g. `manylinux_2_17_x86_64`. +:platform_suffix: is a derivative of the `platform_tag` and is used to implement selection based on `libc` or `osx` version. + +All of the config settings used by this macro are generated by +{obj}`config_settings`, for more detailed documentation on what each config +setting maps to and their precedence, refer to documentation on that page. + +The first group of config settings that are as follows: + +* `//_config:is_cp3` is used to select legacy `pip` + based `whl` and `sdist` {obj}`whl_library` instances. Whereas other config + settings are created when {obj}`pip.parse.experimental_index_url` is used. +* `//_config:is_cp3_sdist` is for wheels built from + `sdist` in {obj}`whl_library`. +* `//_config:is_cp3_py__any` for wheels with + `py2.py3` `python_tag` value. +* `//_config:is_cp3_py3__any` for wheels with + `py3` `python_tag` value. +* `//_config:is_cp3__any` for any other wheels. +* `//_config:is_cp3_py__` for + platform-specific wheels with `py2.py3` `python_tag` value. +* `//_config:is_cp3_py3__` for + platform-specific wheels with `py3` `python_tag` value. +* `//_config:is_cp3__` for any other + platform-specific wheels. + +Note that wheels with `abi3` or `none` `abi_tag` values and `python_tag` values +other than `py2.py3` or `py3` are compatible with the python version that is +equal or higher than the one denoted in the `python_tag`. For example: `py37` +and `cp37` wheels are compatible with Python 3.7 and above and in the case of +the target python version being `3.11`, `rules_python` will use +`//_config:is_cp311__any` config settings. + +For platform-specific wheels, i.e. the ones that have their `platform_tag` as +something else than `any`, we treat them as below: +* `linux_` tags assume that the target `libc` flavour is `glibc`, so this + is in many ways equivalent to it being `manylinux`, but with an unspecified + `libc` version. +* For `osx` and `linux` OSes wheel filename will be mapped to multiple config settings: + * `osx_` and `osx___` where + `major_version` and `minor_version` are the compatible OSX versions. + * `linux_` and + `linux___` where the version + identifiers are the compatible libc versions. + +[packaging_spec]: https://packaging.python.org/en/latest/specifications/platform-compatibility-tags/ +""" load("@bazel_skylib//lib:selects.bzl", "selects") load("//python/private:text_util.bzl", "render") @@ -66,11 +123,11 @@ def pkg_aliases( actual, group_name = None, extra_aliases = None, - native = native, - select = selects.with_or, **kwargs): """Create aliases for an actual package. + Exposed only to be used from the hub repositories created by `rules_python`. + Args: name: {type}`str` The name of the package. actual: {type}`dict[Label | tuple, str] | str` The name of the repo the @@ -79,11 +136,12 @@ def pkg_aliases( to bazel skylib's `selects.with_or`, so they can be tuples as well. group_name: {type}`str` The group name that the pkg belongs to. extra_aliases: {type}`list[str]` The extra aliases to be created. - native: {type}`struct` used in unit tests. - select: {type}`select` used in unit tests. **kwargs: extra kwargs to pass to {bzl:obj}`get_filename_config_settings`. """ - native.alias( + alias = kwargs.pop("native", native).alias + select = kwargs.pop("select", selects.with_or) + + alias( name = name, actual = ":" + PY_LIBRARY_PUBLIC_LABEL, ) @@ -100,7 +158,7 @@ def pkg_aliases( actual = multiplatform_whl_aliases(aliases = actual, **kwargs) if type(actual) == type({}) and "//conditions:default" not in actual: - native.alias( + alias( name = _INCOMPATIBLE, actual = select( {_LABEL_CURRENT_CONFIG_NO_MATCH: _LABEL_NONE}, @@ -143,18 +201,18 @@ def pkg_aliases( if target_name.startswith("_"): kwargs["visibility"] = ["//_groups:__subpackages__"] - native.alias( + alias( name = target_name, actual = _actual, **kwargs ) if group_name: - native.alias( + alias( name = PY_LIBRARY_PUBLIC_LABEL, actual = "//_groups:{}_pkg".format(group_name), ) - native.alias( + alias( name = WHEEL_FILE_PUBLIC_LABEL, actual = "//_groups:{}_whl".format(group_name), ) @@ -176,6 +234,8 @@ def multiplatform_whl_aliases( osx_versions = []): """convert a list of aliases from filename to config_setting ones. + Exposed only for unit tests. + Args: aliases: {type}`str | dict[whl_config_setting | str, str]`: The aliases to process. Any aliases that have the filename set will be @@ -277,6 +337,8 @@ def get_filename_config_settings( non_whl_prefix = "sdist"): """Get the filename config settings. + Exposed only for unit tests. + Args: filename: the distribution filename (can be a whl or an sdist). target_platforms: list[str], target platforms in "{abi}_{os}_{cpu}" format. @@ -299,23 +361,20 @@ def get_filename_config_settings( if filename.endswith(".whl"): parsed = parse_whl_name(filename) if parsed.python_tag == "py2.py3": - py = "py" + py = "py_" + elif parsed.python_tag == "py3": + py = "py3_" elif parsed.python_tag.startswith("cp"): - py = "cp3x" + py = "" else: - py = "py3" + py = "py3_" - if parsed.abi_tag.startswith("cp") and parsed.abi_tag.endswith("t"): - abi = "cpt" - elif parsed.abi_tag.startswith("cp"): - abi = "cp" - else: - abi = parsed.abi_tag + abi = parsed.abi_tag if parsed.platform_tag == "any": - prefixes = ["_{}_{}_any".format(py, abi)] + prefixes = ["{}{}_any".format(py, abi)] else: - prefixes = ["_{}_{}".format(py, abi)] + prefixes = ["{}{}".format(py, abi)] suffixes = _whl_config_setting_suffixes( platform_tag = parsed.platform_tag, glibc_versions = glibc_versions, @@ -324,14 +383,20 @@ def get_filename_config_settings( setting_supported_versions = setting_supported_versions, ) else: - prefixes = [""] if not non_whl_prefix else ["_" + non_whl_prefix] + prefixes = [non_whl_prefix or ""] + + py = "cp{}".format(python_version).replace(".", "") + prefixes = [ + "{}_{}".format(py, prefix) if prefix else py + for prefix in prefixes + ] versioned = { - ":is_cp{}{}_{}".format(python_version, p, suffix): { - version: ":is_cp{}{}_{}".format(python_version, p, setting) + ":is_{}_{}".format(prefix, suffix): { + version: ":is_{}_{}".format(prefix, setting) for version, setting in versions.items() } - for p in prefixes + for prefix in prefixes for suffix, versions in setting_supported_versions.items() } @@ -339,12 +404,12 @@ def get_filename_config_settings( target_platforms = target_platforms or [] suffixes = suffixes or [_non_versioned_platform(p) for p in target_platforms] return [ - ":is_cp{}{}_{}".format(python_version, p, s) - for p in prefixes - for s in suffixes + ":is_{}_{}".format(prefix, suffix) + for prefix in prefixes + for suffix in suffixes ], versioned else: - return [":is_cp{}{}".format(python_version, p) for p in prefixes], setting_supported_versions + return [":is_{}".format(p) for p in prefixes], setting_supported_versions def _whl_config_setting_suffixes( platform_tag, @@ -368,7 +433,7 @@ def _whl_config_setting_suffixes( elif p.os == "osx": versions = osx_versions if "universal2" in platform_tag: - suffix += "_universal2" + suffix = "universal2" else: fail("Unsupported whl os: {}".format(p.os)) diff --git a/python/private/pypi/render_pkg_aliases.bzl b/python/private/pypi/render_pkg_aliases.bzl index 62c893d3e7..863d25095c 100644 --- a/python/private/pypi/render_pkg_aliases.bzl +++ b/python/private/pypi/render_pkg_aliases.bzl @@ -60,7 +60,7 @@ def _repr_config_setting(alias): ) else: return repr( - alias.config_setting or ("//_config:is_python_" + alias.version), + alias.config_setting or "//_config:is_cp{}".format(alias.version.replace(".", "")), ) def _repr_actual(aliases): diff --git a/tests/pypi/config_settings/config_settings_tests.bzl b/tests/pypi/config_settings/config_settings_tests.bzl index 049556a4c6..f111d0c55c 100644 --- a/tests/pypi/config_settings/config_settings_tests.bzl +++ b/tests/pypi/config_settings/config_settings_tests.bzl @@ -72,24 +72,61 @@ def _match(env, target, want): _tests = [] +# Legacy pip config setting tests + +def _test_legacy_default(name): + _analysis_test( + name = name, + dist = { + "is_cp37": "legacy", + }, + want = "legacy", + ) + +_tests.append(_test_legacy_default) + +def _test_legacy_with_constraint_values(name): + _analysis_test( + name = name, + dist = { + "is_cp37": "legacy", + "is_cp37_linux_aarch64": "legacy_platform_override", + }, + want = "legacy_platform_override", + ) + +_tests.append(_test_legacy_with_constraint_values) + # Tests when we only have an `sdist` present. def _test_sdist_default(name): _analysis_test( name = name, dist = { - "is_cp3.7_sdist": "sdist", + "is_cp37_sdist": "sdist", }, want = "sdist", ) _tests.append(_test_sdist_default) +def _test_legacy_less_specialized_than_sdist(name): + _analysis_test( + name = name, + dist = { + "is_cp37": "legacy", + "is_cp37_sdist": "sdist", + }, + want = "sdist", + ) + +_tests.append(_test_legacy_less_specialized_than_sdist) + def _test_sdist_no_whl(name): _analysis_test( name = name, dist = { - "is_cp3.7_sdist": "sdist", + "is_cp37_sdist": "sdist", }, config_settings = [ _flag.platform("linux_aarch64"), @@ -104,7 +141,7 @@ def _test_sdist_no_sdist(name): _analysis_test( name = name, dist = { - "is_cp3.7_sdist": "sdist", + "is_cp37_sdist": "sdist", }, config_settings = [ _flag.platform("linux_aarch64"), @@ -121,8 +158,8 @@ def _test_basic_whl_default(name): _analysis_test( name = name, dist = { - "is_cp3.7_py_none_any": "whl", - "is_cp3.7_sdist": "sdist", + "is_cp37_py_none_any": "whl", + "is_cp37_sdist": "sdist", }, want = "whl", ) @@ -133,8 +170,8 @@ def _test_basic_whl_nowhl(name): _analysis_test( name = name, dist = { - "is_cp3.7_py_none_any": "whl", - "is_cp3.7_sdist": "sdist", + "is_cp37_py_none_any": "whl", + "is_cp37_sdist": "sdist", }, config_settings = [ _flag.platform("linux_aarch64"), @@ -149,8 +186,8 @@ def _test_basic_whl_nosdist(name): _analysis_test( name = name, dist = { - "is_cp3.7_py_none_any": "whl", - "is_cp3.7_sdist": "sdist", + "is_cp37_py_none_any": "whl", + "is_cp37_sdist": "sdist", }, config_settings = [ _flag.platform("linux_aarch64"), @@ -165,8 +202,8 @@ def _test_whl_default(name): _analysis_test( name = name, dist = { - "is_cp3.7_py3_none_any": "whl", - "is_cp3.7_py_none_any": "basic_whl", + "is_cp37_py3_none_any": "whl", + "is_cp37_py_none_any": "basic_whl", }, want = "whl", ) @@ -177,8 +214,8 @@ def _test_whl_nowhl(name): _analysis_test( name = name, dist = { - "is_cp3.7_py3_none_any": "whl", - "is_cp3.7_py_none_any": "basic_whl", + "is_cp37_py3_none_any": "whl", + "is_cp37_py_none_any": "basic_whl", }, config_settings = [ _flag.platform("linux_aarch64"), @@ -193,7 +230,7 @@ def _test_whl_nosdist(name): _analysis_test( name = name, dist = { - "is_cp3.7_py3_none_any": "whl", + "is_cp37_py3_none_any": "whl", }, config_settings = [ _flag.platform("linux_aarch64"), @@ -208,8 +245,8 @@ def _test_abi_whl_is_prefered(name): _analysis_test( name = name, dist = { - "is_cp3.7_py3_abi3_any": "abi_whl", - "is_cp3.7_py3_none_any": "whl", + "is_cp37_py3_abi3_any": "abi_whl", + "is_cp37_py3_none_any": "whl", }, want = "abi_whl", ) @@ -220,9 +257,9 @@ def _test_whl_with_constraints_is_prefered(name): _analysis_test( name = name, dist = { - "is_cp3.7_py3_none_any": "default_whl", - "is_cp3.7_py3_none_any_linux_aarch64": "whl", - "is_cp3.7_py3_none_any_linux_x86_64": "amd64_whl", + "is_cp37_py3_none_any": "default_whl", + "is_cp37_py3_none_any_linux_aarch64": "whl", + "is_cp37_py3_none_any_linux_x86_64": "amd64_whl", }, want = "whl", ) @@ -233,9 +270,9 @@ def _test_cp_whl_is_prefered_over_py3(name): _analysis_test( name = name, dist = { - "is_cp3.7_cp3x_none_any": "cp", - "is_cp3.7_py3_abi3_any": "py3_abi3", - "is_cp3.7_py3_none_any": "py3", + "is_cp37_none_any": "cp", + "is_cp37_py3_abi3_any": "py3_abi3", + "is_cp37_py3_none_any": "py3", }, want = "cp", ) @@ -246,8 +283,8 @@ def _test_cp_abi_whl_is_prefered_over_py3(name): _analysis_test( name = name, dist = { - "is_cp3.7_cp3x_abi3_any": "cp", - "is_cp3.7_py3_abi3_any": "py3", + "is_cp37_abi3_any": "cp", + "is_cp37_py3_abi3_any": "py3", }, want = "cp", ) @@ -258,9 +295,9 @@ def _test_cp_version_is_selected_when_python_version_is_specified(name): _analysis_test( name = name, dist = { - "is_cp3.10_cp3x_none_any": "cp310", - "is_cp3.8_cp3x_none_any": "cp38", - "is_cp3.9_cp3x_none_any": "cp39", + "is_cp310_none_any": "cp310", + "is_cp38_none_any": "cp38", + "is_cp39_none_any": "cp39", }, want = "cp310", config_settings = [ @@ -275,8 +312,8 @@ def _test_py_none_any_versioned(name): _analysis_test( name = name, dist = { - "is_cp3.10_py_none_any": "whl", - "is_cp3.9_py_none_any": "too-low", + "is_cp310_py_none_any": "whl", + "is_cp39_py_none_any": "too-low", }, want = "whl", config_settings = [ @@ -291,9 +328,9 @@ def _test_cp_whl_is_not_prefered_over_py3_non_freethreaded(name): _analysis_test( name = name, dist = { - "is_cp3.7_cp3x_abi3_any": "py3_abi3", - "is_cp3.7_cp3x_cpt_any": "cp", - "is_cp3.7_cp3x_none_any": "py3", + "is_cp37_abi3_any": "py3_abi3", + "is_cp37_cp37t_any": "cp", + "is_cp37_none_any": "py3", }, want = "py3_abi3", config_settings = [ @@ -307,9 +344,9 @@ def _test_cp_whl_is_not_prefered_over_py3_freethreaded(name): _analysis_test( name = name, dist = { - "is_cp3.7_cp3x_abi3_any": "py3_abi3", - "is_cp3.7_cp3x_cp_any": "cp", - "is_cp3.7_cp3x_none_any": "py3", + "is_cp37_abi3_any": "py3_abi3", + "is_cp37_cp37_any": "cp", + "is_cp37_none_any": "py3", }, want = "py3", config_settings = [ @@ -323,7 +360,7 @@ def _test_cp_cp_whl(name): _analysis_test( name = name, dist = { - "is_cp3.10_cp3x_cp_linux_aarch64": "whl", + "is_cp310_cp310_linux_aarch64": "whl", }, want = "whl", config_settings = [ @@ -338,7 +375,7 @@ def _test_cp_version_sdist_is_selected(name): _analysis_test( name = name, dist = { - "is_cp3.10_sdist": "sdist", + "is_cp310_sdist": "sdist", }, want = "sdist", config_settings = [ @@ -349,15 +386,52 @@ def _test_cp_version_sdist_is_selected(name): _tests.append(_test_cp_version_sdist_is_selected) +# NOTE: Right now there is no way to get the following behaviour without +# breaking other tests. We need to choose either ta have the correct +# specialization behaviour between `is_cp37_cp37_any` and +# `is_cp37_cp37_any_linux_aarch64` or this commented out test case. +# +# I think having this behaviour not working is fine because the `suffix` +# will be either present on all of config settings of the same platform +# or none, because we use it as a way to select a separate version of the +# wheel for a single platform only. +# +# If we can think of a better way to handle it, then we can lift this +# limitation. +# +# def _test_any_whl_with_suffix_specialization(name): +# _analysis_test( +# name = name, +# dist = { +# "is_cp37_abi3_any_linux_aarch64": "abi3", +# "is_cp37_cp37_any": "cp37", +# }, +# want = "cp37", +# ) +# +# _tests.append(_test_any_whl_with_suffix_specialization) + +def _test_platform_vs_any_with_suffix_specialization(name): + _analysis_test( + name = name, + dist = { + "is_cp37_cp37_any_linux_aarch64": "any", + "is_cp37_py3_none_linux_aarch64": "platform_whl", + }, + want = "platform_whl", + ) + +_tests.append(_test_platform_vs_any_with_suffix_specialization) + def _test_platform_whl_is_prefered_over_any_whl_with_constraints(name): _analysis_test( name = name, dist = { - "is_cp3.7_py3_abi3_any": "better_default_whl", - "is_cp3.7_py3_abi3_any_linux_aarch64": "better_default_any_whl", - "is_cp3.7_py3_none_any": "default_whl", - "is_cp3.7_py3_none_any_linux_aarch64": "whl", - "is_cp3.7_py3_none_linux_aarch64": "platform_whl", + "is_cp37_py3_abi3_any": "better_default_whl", + "is_cp37_py3_abi3_any_linux_aarch64": "better_default_any_whl", + "is_cp37_py3_none_any": "default_whl", + "is_cp37_py3_none_any_linux_aarch64": "whl", + "is_cp37_py3_none_linux_aarch64": "platform_whl", }, want = "platform_whl", ) @@ -368,8 +442,8 @@ def _test_abi3_platform_whl_preference(name): _analysis_test( name = name, dist = { - "is_cp3.7_py3_abi3_linux_aarch64": "abi3_platform", - "is_cp3.7_py3_none_linux_aarch64": "platform", + "is_cp37_py3_abi3_linux_aarch64": "abi3_platform", + "is_cp37_py3_none_linux_aarch64": "platform", }, want = "abi3_platform", ) @@ -380,8 +454,8 @@ def _test_glibc(name): _analysis_test( name = name, dist = { - "is_cp3.7_cp3x_cp_manylinux_aarch64": "glibc", - "is_cp3.7_py3_abi3_linux_aarch64": "abi3_platform", + "is_cp37_cp37_manylinux_aarch64": "glibc", + "is_cp37_py3_abi3_linux_aarch64": "abi3_platform", }, want = "glibc", ) @@ -392,9 +466,9 @@ def _test_glibc_versioned(name): _analysis_test( name = name, dist = { - "is_cp3.7_cp3x_cp_manylinux_2_14_aarch64": "glibc", - "is_cp3.7_cp3x_cp_manylinux_2_17_aarch64": "glibc", - "is_cp3.7_py3_abi3_linux_aarch64": "abi3_platform", + "is_cp37_cp37_manylinux_2_14_aarch64": "glibc", + "is_cp37_cp37_manylinux_2_17_aarch64": "glibc", + "is_cp37_py3_abi3_linux_aarch64": "abi3_platform", }, want = "glibc", config_settings = [ @@ -412,8 +486,8 @@ def _test_glibc_compatible_exists(name): dist = { # Code using the conditions will need to construct selects, which # do the version matching correctly. - "is_cp3.7_cp3x_cp_manylinux_2_14_aarch64": "2_14_whl_via_2_14_branch", - "is_cp3.7_cp3x_cp_manylinux_2_17_aarch64": "2_14_whl_via_2_17_branch", + "is_cp37_cp37_manylinux_2_14_aarch64": "2_14_whl_via_2_14_branch", + "is_cp37_cp37_manylinux_2_17_aarch64": "2_14_whl_via_2_17_branch", }, want = "2_14_whl_via_2_17_branch", config_settings = [ @@ -429,7 +503,7 @@ def _test_musl(name): _analysis_test( name = name, dist = { - "is_cp3.7_cp3x_cp_musllinux_aarch64": "musl", + "is_cp37_cp37_musllinux_aarch64": "musl", }, want = "musl", config_settings = [ @@ -444,8 +518,8 @@ def _test_windows(name): _analysis_test( name = name, dist = { - "is_cp3.7_cp3x_cp_windows_x86_64": "whl", - "is_cp3.7_cp3x_cpt_windows_x86_64": "whl_freethreaded", + "is_cp37_cp37_windows_x86_64": "whl", + "is_cp37_cp37t_windows_x86_64": "whl_freethreaded", }, want = "whl", config_settings = [ @@ -459,8 +533,8 @@ def _test_windows_freethreaded(name): _analysis_test( name = name, dist = { - "is_cp3.7_cp3x_cp_windows_x86_64": "whl", - "is_cp3.7_cp3x_cpt_windows_x86_64": "whl_freethreaded", + "is_cp37_cp37_windows_x86_64": "whl", + "is_cp37_cp37t_windows_x86_64": "whl_freethreaded", }, want = "whl_freethreaded", config_settings = [ @@ -476,8 +550,8 @@ def _test_osx(name): name = name, dist = { # We prefer arch specific whls over universal - "is_cp3.7_cp3x_cp_osx_x86_64": "whl", - "is_cp3.7_cp3x_cp_osx_x86_64_universal2": "universal_whl", + "is_cp37_cp37_osx_universal2": "universal_whl", + "is_cp37_cp37_osx_x86_64": "whl", }, want = "whl", config_settings = [ @@ -492,7 +566,7 @@ def _test_osx_universal_default(name): name = name, dist = { # We default to universal if only that exists - "is_cp3.7_cp3x_cp_osx_x86_64_universal2": "whl", + "is_cp37_cp37_osx_universal2": "whl", }, want = "whl", config_settings = [ @@ -507,8 +581,8 @@ def _test_osx_universal_only(name): name = name, dist = { # If we prefer universal, then we use that - "is_cp3.7_cp3x_cp_osx_x86_64": "whl", - "is_cp3.7_cp3x_cp_osx_x86_64_universal2": "universal", + "is_cp37_cp37_osx_universal2": "universal", + "is_cp37_cp37_osx_x86_64": "whl", }, want = "universal", config_settings = [ @@ -525,7 +599,7 @@ def _test_osx_os_version(name): dist = { # Similarly to the libc version, the user of the config settings will have to # construct the select so that the version selection is correct. - "is_cp3.7_cp3x_cp_osx_10_9_x86_64": "whl", + "is_cp37_cp37_osx_10_9_x86_64": "whl", }, want = "whl", config_settings = [ @@ -540,15 +614,15 @@ def _test_all(name): _analysis_test( name = name, dist = { - "is_cp3.7_" + f: f + "is_cp37_" + f: f for f in [ - "{py}_{abi}_{plat}".format(py = valid_py, abi = valid_abi, plat = valid_plat) - # we have py2.py3, py3, cp3x - for valid_py in ["py", "py3", "cp3x"] + "{py}{abi}_{plat}".format(py = valid_py, abi = valid_abi, plat = valid_plat) + # we have py2.py3, py3, cp3 + for valid_py in ["py_", "py3_", ""] # cp abi usually comes with a version and we only need one # config setting variant for all of them because the python # version will discriminate between different versions. - for valid_abi in ["none", "abi3", "cp"] + for valid_abi in ["none", "abi3", "cp37"] for valid_plat in [ "any", "manylinux_2_17_x86_64", @@ -557,12 +631,12 @@ def _test_all(name): "windows_x86_64", ] if not ( - valid_abi == "abi3" and valid_py == "py" or - valid_abi == "cp" and valid_py != "cp3x" + valid_abi == "abi3" and valid_py == "py_" or + valid_abi == "cp37" and valid_py != "" ) ] }, - want = "cp3x_cp_manylinux_2_17_x86_64", + want = "cp37_manylinux_2_17_x86_64", config_settings = [ _flag.pip_whl_glibc_version("2.17"), _flag.platform("linux_x86_64"), diff --git a/tests/pypi/pkg_aliases/pkg_aliases_test.bzl b/tests/pypi/pkg_aliases/pkg_aliases_test.bzl index f13b62f13d..71ca811fee 100644 --- a/tests/pypi/pkg_aliases/pkg_aliases_test.bzl +++ b/tests/pypi/pkg_aliases/pkg_aliases_test.bzl @@ -186,9 +186,9 @@ def _test_multiplatform_whl_aliases(env): want = { "pkg": { "//:my_config_setting": "@bzlmod_repo//:pkg", - "//_config:is_cp3.9_linux_x86_64": "@bzlmod_repo_for_a_particular_platform//:pkg", - "//_config:is_cp3.9_py3_none_any": "@filename_repo//:pkg", - "//_config:is_cp3.9_py3_none_any_linux_x86_64": "@filename_repo_for_platform//:pkg", + "//_config:is_cp39_linux_x86_64": "@bzlmod_repo_for_a_particular_platform//:pkg", + "//_config:is_cp39_py3_none_any": "@filename_repo//:pkg", + "//_config:is_cp39_py3_none_any_linux_x86_64": "@filename_repo_for_platform//:pkg", "//conditions:default": "_no_matching_repository", }, } @@ -197,9 +197,9 @@ def _test_multiplatform_whl_aliases(env): env.expect.that_str(actual_no_match_error[0]).contains("""\ configuration settings: //:my_config_setting - //_config:is_cp3.9_linux_x86_64 - //_config:is_cp3.9_py3_none_any - //_config:is_cp3.9_py3_none_any_linux_x86_64 + //_config:is_cp39_linux_x86_64 + //_config:is_cp39_py3_none_any + //_config:is_cp39_py3_none_any_linux_x86_64 """) @@ -286,8 +286,8 @@ def _test_multiplatform_whl_aliases_nofilename_target_platforms(env): got = multiplatform_whl_aliases(aliases = aliases) want = { - "//_config:is_cp3.1_linux_aarch64": "foo", - "//_config:is_cp3.1_linux_x86_64": "foo", + "//_config:is_cp31_linux_aarch64": "foo", + "//_config:is_cp31_linux_x86_64": "foo", } env.expect.that_dict(got).contains_exactly(want) @@ -305,11 +305,11 @@ def _test_multiplatform_whl_aliases_filename(env): ): "foo-py3-0.0.1", whl_config_setting( filename = "foo-0.0.1-cp313-cp313-any.whl", - version = "3.1", + version = "3.13", ): "foo-cp-0.0.1", whl_config_setting( filename = "foo-0.0.1-cp313-cp313t-any.whl", - version = "3.1", + version = "3.13", ): "foo-cpt-0.0.1", whl_config_setting( filename = "foo-0.0.2-py3-none-any.whl", @@ -327,12 +327,12 @@ def _test_multiplatform_whl_aliases_filename(env): osx_versions = [], ) want = { - "//_config:is_cp3.1_cp3x_cp_any": "foo-cp-0.0.1", - "//_config:is_cp3.1_cp3x_cpt_any": "foo-cpt-0.0.1", - "//_config:is_cp3.1_py3_none_any": "foo-py3-0.0.1", - "//_config:is_cp3.1_py3_none_any_linux_aarch64": "foo-0.0.2", - "//_config:is_cp3.1_py3_none_any_linux_x86_64": "foo-0.0.2", - "//_config:is_cp3.2_py3_none_any": "foo-py3-0.0.3", + "//_config:is_cp313_cp313_any": "foo-cp-0.0.1", + "//_config:is_cp313_cp313t_any": "foo-cpt-0.0.1", + "//_config:is_cp31_py3_none_any": "foo-py3-0.0.1", + "//_config:is_cp31_py3_none_any_linux_aarch64": "foo-0.0.2", + "//_config:is_cp31_py3_none_any_linux_x86_64": "foo-0.0.2", + "//_config:is_cp32_py3_none_any": "foo-py3-0.0.3", } env.expect.that_dict(got).contains_exactly(want) @@ -378,12 +378,12 @@ def _test_multiplatform_whl_aliases_filename_versioned(env): # For this to fully work we need to have the pypi:config_settings.bzl to generate the # extra targets that use the FeatureFlagInfo and this to generate extra aliases for the # config settings. - "//_config:is_cp3.1_py3_none_manylinux_2_17_x86_64": "glibc-2.17", - "//_config:is_cp3.1_py3_none_manylinux_2_18_x86_64": "glibc-2.18", - "//_config:is_cp3.1_py3_none_manylinux_x86_64": "glibc-2.17", - "//_config:is_cp3.1_py3_none_musllinux_1_1_x86_64": "musl-1.1", - "//_config:is_cp3.1_py3_none_musllinux_1_2_x86_64": "musl-1.1", - "//_config:is_cp3.1_py3_none_musllinux_x86_64": "musl-1.1", + "//_config:is_cp31_py3_none_manylinux_2_17_x86_64": "glibc-2.17", + "//_config:is_cp31_py3_none_manylinux_2_18_x86_64": "glibc-2.18", + "//_config:is_cp31_py3_none_manylinux_x86_64": "glibc-2.17", + "//_config:is_cp31_py3_none_musllinux_1_1_x86_64": "musl-1.1", + "//_config:is_cp31_py3_none_musllinux_1_2_x86_64": "musl-1.1", + "//_config:is_cp31_py3_none_musllinux_x86_64": "musl-1.1", } env.expect.that_dict(got).contains_exactly(want) diff --git a/tests/pypi/render_pkg_aliases/render_pkg_aliases_test.bzl b/tests/pypi/render_pkg_aliases/render_pkg_aliases_test.bzl index ca1651aa1d..c60761bed7 100644 --- a/tests/pypi/render_pkg_aliases/render_pkg_aliases_test.bzl +++ b/tests/pypi/render_pkg_aliases/render_pkg_aliases_test.bzl @@ -341,7 +341,7 @@ def _test_sdist(env): env, filename = "foo-0.0.1" + ext, python_version = "3.2", - want = [":is_cp3.2_sdist"], + want = [":is_cp32_sdist"], ) ext = ".zip" @@ -354,8 +354,8 @@ def _test_sdist(env): "linux_x86_64", ], want = [ - ":is_cp3.2_sdist_linux_aarch64", - ":is_cp3.2_sdist_linux_x86_64", + ":is_cp32_sdist_linux_aarch64", + ":is_cp32_sdist_linux_x86_64", ], ) @@ -367,7 +367,7 @@ def _test_py2_py3_none_any(env): filename = "foo-0.0.1-py2.py3-none-any.whl", python_version = "3.2", want = [ - ":is_cp3.2_py_none_any", + ":is_cp32_py_none_any", ], ) @@ -378,7 +378,7 @@ def _test_py2_py3_none_any(env): target_platforms = [ "osx_x86_64", ], - want = [":is_cp3.2_py_none_any_osx_x86_64"], + want = [":is_cp32_py_none_any_osx_x86_64"], ) _tests.append(_test_py2_py3_none_any) @@ -388,7 +388,7 @@ def _test_py3_none_any(env): env, filename = "foo-0.0.1-py3-none-any.whl", python_version = "3.1", - want = [":is_cp3.1_py3_none_any"], + want = [":is_cp31_py3_none_any"], ) _test_config_settings( @@ -396,7 +396,7 @@ def _test_py3_none_any(env): filename = "foo-0.0.1-py3-none-any.whl", python_version = "3.1", target_platforms = ["linux_x86_64"], - want = [":is_cp3.1_py3_none_any_linux_x86_64"], + want = [":is_cp31_py3_none_any_linux_x86_64"], ) _tests.append(_test_py3_none_any) @@ -412,13 +412,9 @@ def _test_py3_none_macosx_10_9_universal2(env): ], want = [], want_versions = { - ":is_cp3.1_py3_none_osx_aarch64_universal2": { - (10, 9): ":is_cp3.1_py3_none_osx_10_9_aarch64_universal2", - (11, 0): ":is_cp3.1_py3_none_osx_11_0_aarch64_universal2", - }, - ":is_cp3.1_py3_none_osx_x86_64_universal2": { - (10, 9): ":is_cp3.1_py3_none_osx_10_9_x86_64_universal2", - (11, 0): ":is_cp3.1_py3_none_osx_11_0_x86_64_universal2", + ":is_cp31_py3_none_osx_universal2": { + (10, 9): ":is_cp31_py3_none_osx_10_9_universal2", + (11, 0): ":is_cp31_py3_none_osx_11_0_universal2", }, }, ) @@ -430,7 +426,7 @@ def _test_cp37_abi3_linux_x86_64(env): env, filename = "foo-0.0.1-cp37-abi3-linux_x86_64.whl", python_version = "3.7", - want = [":is_cp3.7_cp3x_abi3_linux_x86_64"], + want = [":is_cp37_abi3_linux_x86_64"], ) _tests.append(_test_cp37_abi3_linux_x86_64) @@ -440,7 +436,7 @@ def _test_cp37_abi3_windows_x86_64(env): env, filename = "foo-0.0.1-cp37-abi3-windows_x86_64.whl", python_version = "3.7", - want = [":is_cp3.7_cp3x_abi3_windows_x86_64"], + want = [":is_cp37_abi3_windows_x86_64"], ) _tests.append(_test_cp37_abi3_windows_x86_64) @@ -457,9 +453,9 @@ def _test_cp37_abi3_manylinux_2_17_x86_64(env): ], want = [], want_versions = { - ":is_cp3.7_cp3x_abi3_manylinux_x86_64": { - (2, 17): ":is_cp3.7_cp3x_abi3_manylinux_2_17_x86_64", - (2, 18): ":is_cp3.7_cp3x_abi3_manylinux_2_18_x86_64", + ":is_cp37_abi3_manylinux_x86_64": { + (2, 17): ":is_cp37_abi3_manylinux_2_17_x86_64", + (2, 18): ":is_cp37_abi3_manylinux_2_18_x86_64", }, }, ) @@ -482,12 +478,12 @@ def _test_cp37_abi3_manylinux_2_17_musllinux_1_1_aarch64(env): ], want = [], want_versions = { - ":is_cp3.7_cp3x_cp_manylinux_aarch64": { - (2, 17): ":is_cp3.7_cp3x_cp_manylinux_2_17_aarch64", - (2, 18): ":is_cp3.7_cp3x_cp_manylinux_2_18_aarch64", + ":is_cp37_cp37_manylinux_aarch64": { + (2, 17): ":is_cp37_cp37_manylinux_2_17_aarch64", + (2, 18): ":is_cp37_cp37_manylinux_2_18_aarch64", }, - ":is_cp3.7_cp3x_cp_musllinux_aarch64": { - (1, 1): ":is_cp3.7_cp3x_cp_musllinux_1_1_aarch64", + ":is_cp37_cp37_musllinux_aarch64": { + (1, 1): ":is_cp37_cp37_musllinux_1_1_aarch64", }, }, )