From 17de5647aef8ae8a2585f55bdd2b2e389ef7941a Mon Sep 17 00:00:00 2001 From: Ignas Anikevicius <240938+aignas@users.noreply.github.com> Date: Sun, 15 Sep 2024 14:53:53 +0900 Subject: [PATCH 1/8] chore: remove the list of allowed python_version values --- python/private/config_settings.bzl | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/python/private/config_settings.bzl b/python/private/config_settings.bzl index 301a97b25d..307e54a276 100644 --- a/python/private/config_settings.bzl +++ b/python/private/config_settings.bzl @@ -178,7 +178,6 @@ def construct_config_settings(name = None): # buildifier: disable=function-docs # also prevents version-unaware targets from inadvertently matching # a select condition when they shouldn't. build_setting_default = "", - values = [""] + VERSION_FLAG_VALUES.keys(), visibility = ["//visibility:public"], ) @@ -204,14 +203,6 @@ def construct_config_settings(name = None): # buildifier: disable=function-docs def _python_version_flag_impl(ctx): value = ctx.build_setting_value - if value not in ctx.attr.values: - fail(( - "Invalid --python_version value: {actual}\nAllowed values {allowed}" - ).format( - actual = value, - allowed = ", ".join(sorted(ctx.attr.values)), - )) - return [ # BuildSettingInfo is the original provider returned, so continue to # return it for compatibility @@ -227,9 +218,5 @@ def _python_version_flag_impl(ctx): _python_version_flag = rule( implementation = _python_version_flag_impl, build_setting = config.string(flag = True), - attrs = { - "values": attr.string_list( - doc = "Allowed values.", - ), - }, + attrs = {}, ) From 60dae67fd0adc5545cab9db59391eb1239d17f6a Mon Sep 17 00:00:00 2001 From: Ignas Anikevicius <240938+aignas@users.noreply.github.com> Date: Sun, 15 Sep 2024 15:34:13 +0900 Subject: [PATCH 2/8] chore: remove is_python_config_settings With the suggested snippet of code, this greatly simplified the codebase --- CHANGELOG.md | 12 +- MODULE.bazel | 8 + examples/bzlmod/MODULE.bazel.lock | 14 +- python/config_settings/config_settings.bzl | 6 - python/private/config_settings.bzl | 226 ++++++------------ .../pypi/generate_whl_library_build_bazel.bzl | 9 +- .../construct_config_settings_tests.bzl | 19 +- ...generate_whl_library_build_bazel_tests.bzl | 19 +- 8 files changed, 132 insertions(+), 181 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4c99206b1..064663110b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -78,6 +78,16 @@ A brief description of the categories of changes: ### Removed * (toolchains): Removed accidentally exposed `http_archive` symbol from `python/repositories.bzl`. +* (toolchains): An internal _is_python_config_setting_ has been removed + from rules_python as it can now be replaced by: + ```starlark + native.config_setting( + name = "my_config_setting", + flag_values = { + "@rules_python//python/config_settings:python_version_major_minor": "3.11", + }, + ) + ``` ## [0.35.0] - 2024-08-15 @@ -273,7 +283,7 @@ A brief description of the categories of changes: be automatically deleted correctly. For example, if `python_generation_mode` is set to package, when `__init__.py` is deleted, the `py_library` generated for this package before will be deleted automatically. -* (whl_library): Use `is_python_config_setting` to correctly handle multi-python +* (whl_library): Use _is_python_config_setting_ to correctly handle multi-python version dependency select statements when the `experimental_target_platforms` includes the Python ABI. The default python version case within the select is also now handled correctly, stabilizing the implementation. diff --git a/MODULE.bazel b/MODULE.bazel index 9ac3e7a04c..80915eb1de 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -46,6 +46,9 @@ python.toolchain( is_default = True, python_version = "3.11", ) +python.toolchain( + python_version = "3.12", +) use_repo(python, "python_3_11", "python_versions", "pythons_hub") # This call registers the Python toolchains. @@ -95,6 +98,11 @@ dev_pip.parse( python_version = "3.11", requirements_lock = "//docs:requirements.txt", ) +dev_pip.parse( + hub_name = "dev_pip", + python_version = "3.12", + requirements_lock = "//docs:requirements.txt", +) dev_pip.parse( hub_name = "pypiserver", python_version = "3.11", diff --git a/examples/bzlmod/MODULE.bazel.lock b/examples/bzlmod/MODULE.bazel.lock index 0cfe49d5d8..234e3e23ad 100644 --- a/examples/bzlmod/MODULE.bazel.lock +++ b/examples/bzlmod/MODULE.bazel.lock @@ -1231,7 +1231,7 @@ }, "@@rules_python~//python/extensions:pip.bzl%pip": { "general": { - "bzlTransitiveDigest": "7vRndkQ5a5Q2gcPIP8Jd/AkNRuB4n7SofpNFmFvodG8=", + "bzlTransitiveDigest": "RC4E7E0SGJN0zEuYQshtQOt2AhuGQaqLZeqeWpyYohM=", "usagesDigest": "MChlcSw99EuW3K7OOoMcXQIdcJnEh6YmfyjJm+9mxIg=", "recordedFileInputs": { "@@other_module~//requirements_lock_3_11.txt": "a7d0061366569043d5efcf80e34a32c732679367cb3c831c4cdc606adc36d314", @@ -6130,6 +6130,11 @@ "python_3_11_host", "rules_python~~python~python_3_11_host" ], + [ + "rules_python~~python~pythons_hub", + "python_3_12_host", + "rules_python~~python~python_3_12_host" + ], [ "rules_python~~python~pythons_hub", "python_3_9_host", @@ -6140,7 +6145,7 @@ }, "@@rules_python~//python/private/pypi:pip.bzl%pip_internal": { "general": { - "bzlTransitiveDigest": "DQe4hZM+myEcJ/pVW54jl5vWJOw+oZNBZfE0WOX/S9g=", + "bzlTransitiveDigest": "DRpRmfRZxab4y84aleF5p42oIglVd+JQuTWXFx6rsRs=", "usagesDigest": "Y8ihY+R57BAFhalrVLVdJFrpwlbsiKz9JPJ99ljF7HA=", "recordedFileInputs": { "@@rules_python~//tools/publish/requirements.txt": "031e35d03dde03ae6305fe4b3d1f58ad7bdad857379752deede0f93649991b8a", @@ -8387,6 +8392,11 @@ "python_3_11_host", "rules_python~~python~python_3_11_host" ], + [ + "rules_python~~python~pythons_hub", + "python_3_12_host", + "rules_python~~python~python_3_12_host" + ], [ "rules_python~~python~pythons_hub", "python_3_9_host", diff --git a/python/config_settings/config_settings.bzl b/python/config_settings/config_settings.bzl index f1d2ff0e06..44104259b7 100644 --- a/python/config_settings/config_settings.bzl +++ b/python/config_settings/config_settings.bzl @@ -18,13 +18,7 @@ load( "//python/private:config_settings.bzl", _construct_config_settings = "construct_config_settings", - _is_python_config_setting = "is_python_config_setting", ) -# This is exposed only for cases where the pip hub repo needs to use this rule -# to define hub-repo scoped config_settings for platform specific wheel -# support. -is_python_config_setting = _is_python_config_setting - # This is exposed for usage in rules_python only. construct_config_settings = _construct_config_settings diff --git a/python/private/config_settings.bzl b/python/private/config_settings.bzl index 307e54a276..c42803fba6 100644 --- a/python/private/config_settings.bzl +++ b/python/private/config_settings.bzl @@ -18,149 +18,10 @@ load("@bazel_skylib//lib:selects.bzl", "selects") load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo") load("//python:versions.bzl", "MINOR_MAPPING", "TOOL_VERSIONS") +load(":semver.bzl", "semver") _PYTHON_VERSION_FLAG = str(Label("//python/config_settings:python_version")) - -def _ver_key(s): - major, _, s = s.partition(".") - minor, _, s = s.partition(".") - micro, _, s = s.partition(".") - return (int(major), int(minor), int(micro)) - -def _flag_values(*, python_versions, minor_mapping): - """Construct a map of python_version to a list of toolchain values. - - This mapping maps the concept of a config setting to a list of compatible toolchain versions. - For using this in the code, the VERSION_FLAG_VALUES should be used instead. - - Args: - python_versions: {type}`list[str]` X.Y.Z` python versions. - minor_mapping: {type}`dict[str, str]` `X.Y` to `X.Y.Z` mapping. - - Returns: - A `map[str, list[str]]`. Each key is a python_version flag value. Each value - is a list of the python_version flag values that should match when for the - `key`. For example: - ``` - "3.8" -> ["3.8", "3.8.1", "3.8.2", ..., "3.8.19"] # All 3.8 versions - "3.8.2" -> ["3.8.2"] # Only 3.8.2 - "3.8.19" -> ["3.8.19", "3.8"] # The latest version should also match 3.8 so - as when the `3.8` toolchain is used we just use the latest `3.8` toolchain. - this makes the `select("is_python_3.8.19")` work no matter how the user - specifies the latest python version to use. - ``` - """ - ret = {} - - for micro_version in sorted(python_versions, key = _ver_key): - minor_version, _, _ = micro_version.rpartition(".") - - # This matches the raw flag value, e.g. --//python/config_settings:python_version=3.8 - # It's private because matching the concept of e.g. "3.8" value is done - # using the `is_python_X.Y` config setting group, which is aware of the - # minor versions that could match instead. - ret.setdefault(minor_version, [minor_version]).append(micro_version) - - # Ensure that is_python_3.9.8 is matched if python_version is set - # to 3.9 if minor_mapping points to 3.9.8 - default_micro_version = minor_mapping[minor_version] - ret[micro_version] = [micro_version, minor_version] if default_micro_version == micro_version else [micro_version] - - return ret - -VERSION_FLAG_VALUES = _flag_values(python_versions = TOOL_VERSIONS.keys(), minor_mapping = MINOR_MAPPING) - -def is_python_config_setting(name, *, python_version, reuse_conditions = None, **kwargs): - """Create a config setting for matching 'python_version' configuration flag. - - This function is mainly intended for internal use within the `whl_library` and `pip_parse` - machinery. - - The matching of the 'python_version' flag depends on the value passed in - `python_version` and here is the example for `3.8` (but the same applies - to other python versions present in @//python:versions.bzl#TOOL_VERSIONS): - * "3.8" -> ["3.8", "3.8.1", "3.8.2", ..., "3.8.19"] # All 3.8 versions - * "3.8.2" -> ["3.8.2"] # Only 3.8.2 - * "3.8.19" -> ["3.8.19", "3.8"] # The latest version should also match 3.8 so - as when the `3.8` toolchain is used we just use the latest `3.8` toolchain. - this makes the `select("is_python_3.8.19")` work no matter how the user - specifies the latest python version to use. - - Args: - name: name for the target that will be created to be used in select statements. - python_version: The python_version to be passed in the `flag_values` in the - `config_setting`. Depending on the version, the matching python version list - can be as described above. - reuse_conditions: A dict of version to version label for which we should - reuse config_setting targets instead of creating them from scratch. This - is useful when using is_python_config_setting multiple times in the - same package with the same `major.minor` python versions. - **kwargs: extra kwargs passed to the `config_setting`. - """ - if python_version not in name: - fail("The name '{}' must have the python version '{}' in it".format(name, python_version)) - - if python_version not in VERSION_FLAG_VALUES: - fail("The 'python_version' must be known to 'rules_python', choose from the values: {}".format(VERSION_FLAG_VALUES.keys())) - - python_versions = VERSION_FLAG_VALUES[python_version] - extra_flag_values = kwargs.pop("flag_values", {}) - if _PYTHON_VERSION_FLAG in extra_flag_values: - fail("Cannot set '{}' in the flag values".format(_PYTHON_VERSION_FLAG)) - - if len(python_versions) == 1: - native.config_setting( - name = name, - flag_values = { - _PYTHON_VERSION_FLAG: python_version, - } | extra_flag_values, - **kwargs - ) - return - - reuse_conditions = reuse_conditions or {} - create_config_settings = { - "_{}".format(name).replace(python_version, version): {_PYTHON_VERSION_FLAG: version} - for version in python_versions - if not reuse_conditions or version not in reuse_conditions - } - match_any = list(create_config_settings.keys()) - for version, condition in reuse_conditions.items(): - if len(VERSION_FLAG_VALUES[version]) == 1: - match_any.append(condition) - continue - - # Convert the name to an internal label that this function would create, - # so that we are hitting the config_setting and not the config_setting_group. - condition = Label(condition) - if hasattr(condition, "same_package_label"): - condition = condition.same_package_label("_" + condition.name) - else: - condition = condition.relative("_" + condition.name) - - match_any.append(condition) - - for name_, flag_values_ in create_config_settings.items(): - native.config_setting( - name = name_, - flag_values = flag_values_ | extra_flag_values, - **kwargs - ) - - # An alias pointing to an underscore-prefixed config_setting_group - # is used because config_setting_group creates - # `is_{version}_N` targets, which are easily confused with the - # `is_{minor}.{micro}` (dot) targets. - selects.config_setting_group( - name = "_{}_group".format(name), - match_any = match_any, - visibility = ["//visibility:private"], - ) - native.alias( - name = name, - actual = "_{}_group".format(name), - visibility = kwargs.get("visibility", []), - ) +_PYTHON_MINOR_VERSION_FLAG = str(Label("//python/config_settings:python_version_major_minor")) def construct_config_settings(name = None): # buildifier: disable=function-docstring """Create a 'python_version' config flag and construct all config settings used in rules_python. @@ -181,23 +42,62 @@ def construct_config_settings(name = None): # buildifier: disable=function-docs visibility = ["//visibility:public"], ) + _python_major_minor( + name = "python_version_major_minor", + build_setting_default = "", + visibility = ["//visibility:public"], + ) + native.config_setting( name = "is_python_version_unset", - flag_values = { - Label("//python/config_settings:python_version"): "", - }, + flag_values = {_PYTHON_VERSION_FLAG: ""}, visibility = ["//visibility:public"], ) - for version, matching_versions in VERSION_FLAG_VALUES.items(): - is_python_config_setting( - name = "is_python_{}".format(version), - python_version = version, - reuse_conditions = { - v: native.package_relative_label("is_python_{}".format(v)) - for v in matching_versions - if v != version - }, + # This matches the raw flag value, e.g. --//python/config_settings:python_version=3.8 + # It's private because matching the concept of e.g. "3.8" value is done + # using the `is_python_X.Y` config setting group, which is aware of the + # minor versions that could match instead. + for minor in range(20): + native.config_setting( + name = "is_python_3.{}".format(minor), + flag_values = {_PYTHON_MINOR_VERSION_FLAG: "3.{}".format(minor)}, + visibility = ["//visibility:public"], + ) + + for version in TOOL_VERSIONS.keys(): + minor_version, _, _ = version.rpartition(".") + if MINOR_MAPPING[minor_version] != version: + native.config_setting( + name = "is_python_{}".format(version), + flag_values = {":python_version": version}, + visibility = ["//visibility:public"], + ) + continue + + # Also need to match the minor version when using + name = "is_python_{}".format(version) + native.config_setting( + name = "_" + name, + flag_values = {":python_version": version}, + visibility = ["//visibility:public"], + ) + + # An alias pointing to an underscore-prefixed config_setting_group + # is used because config_setting_group creates + # `is_{version}_N` targets, which are easily confused with the + # `is_{minor}.{micro}` (dot) targets. + selects.config_setting_group( + name = "_{}_group".format(name), + match_any = [ + ":_is_python_{}".format(version), + ":is_python_{}".format(minor_version), + ], + visibility = ["//visibility:private"], + ) + native.alias( + name = name, + actual = "_{}_group".format(name), visibility = ["//visibility:public"], ) @@ -220,3 +120,23 @@ _python_version_flag = rule( build_setting = config.string(flag = True), attrs = {}, ) + +def _python_major_minor_impl(ctx): + input = ctx.attr._python_version_flag[config_common.FeatureFlagInfo].value + if input: + version = semver(input) + value = "{}.{}".format(version.major, version.minor) + else: + value = "" + + return [config_common.FeatureFlagInfo(value = value)] + +_python_major_minor = rule( + implementation = _python_major_minor_impl, + build_setting = config.string(flag = False), + attrs = { + "_python_version_flag": attr.label( + default = _PYTHON_VERSION_FLAG, + ), + }, +) diff --git a/python/private/pypi/generate_whl_library_build_bazel.bzl b/python/private/pypi/generate_whl_library_build_bazel.bzl index d25f73a049..934fa00c69 100644 --- a/python/private/pypi/generate_whl_library_build_bazel.bzl +++ b/python/private/pypi/generate_whl_library_build_bazel.bzl @@ -157,14 +157,13 @@ def _render_config_settings(dependencies_by_platform): constraint_values_str = render.indent(render.list(constraint_values)).lstrip() if abi: - if not loads: - loads.append("""load("@rules_python//python/config_settings:config_settings.bzl", "is_python_config_setting")""") - additional_content.append( """\ -is_python_config_setting( +config_setting( name = "is_{name}", - python_version = "3.{minor_version}", + flag_values = {{ + "@rules_python//python/config_settings:python_version_major_minor": "3.{minor_version}", + }}, constraint_values = {constraint_values}, visibility = ["//visibility:private"], )""".format( diff --git a/tests/config_settings/construct_config_settings_tests.bzl b/tests/config_settings/construct_config_settings_tests.bzl index b1b2e062f9..1e505a7232 100644 --- a/tests/config_settings/construct_config_settings_tests.bzl +++ b/tests/config_settings/construct_config_settings_tests.bzl @@ -18,7 +18,6 @@ load("@rules_testing//lib:analysis_test.bzl", "analysis_test") load("@rules_testing//lib:test_suite.bzl", "test_suite") load("@rules_testing//lib:truth.bzl", "subjects") load("@rules_testing//lib:util.bzl", rt_util = "util") -load("//python/config_settings:config_settings.bzl", "is_python_config_setting") _tests = [] @@ -162,21 +161,25 @@ def construct_config_settings_test_suite(name): # buildifier: disable=function- # We have CI runners running on a great deal of the platforms from the list below, # hence use all of them within tests. for os in ["linux", "osx", "windows"]: - is_python_config_setting( + native.config_setting( name = "is_python_3.11_" + os, constraint_values = [ "@platforms//os:" + os, ], - python_version = "3.11", + flag_values = { + "//python/config_settings:python_version_major_minor": "3.11", + }, ) for cpu in ["s390x", "ppc", "x86_64", "aarch64"]: - is_python_config_setting( + native.config_setting( name = "is_python_3.11_" + cpu, constraint_values = [ "@platforms//cpu:" + cpu, ], - python_version = "3.11", + flag_values = { + "//python/config_settings:python_version_major_minor": "3.11", + }, ) for (os, cpu) in [ @@ -188,13 +191,15 @@ def construct_config_settings_test_suite(name): # buildifier: disable=function- ("osx", "x86_64"), ("windows", "x86_64"), ]: - is_python_config_setting( + native.config_setting( name = "is_python_3.11_{}_{}".format(os, cpu), constraint_values = [ "@platforms//cpu:" + cpu, "@platforms//os:" + os, ], - python_version = "3.11", + flag_values = { + "//python/config_settings:python_version_major_minor": "3.11", + }, ) test_suite( diff --git a/tests/pypi/generate_whl_library_build_bazel/generate_whl_library_build_bazel_tests.bzl b/tests/pypi/generate_whl_library_build_bazel/generate_whl_library_build_bazel_tests.bzl index 3d4df14b5b..94530117cd 100644 --- a/tests/pypi/generate_whl_library_build_bazel/generate_whl_library_build_bazel_tests.bzl +++ b/tests/pypi/generate_whl_library_build_bazel/generate_whl_library_build_bazel_tests.bzl @@ -87,7 +87,6 @@ _tests.append(_test_simple) def _test_dep_selects(env): want = """\ load("@bazel_skylib//rules:copy_file.bzl", "copy_file") -load("@rules_python//python/config_settings:config_settings.bzl", "is_python_config_setting") load("@rules_python//python:defs.bzl", "py_library", "py_binary") package(default_visibility = ["//visibility:public"]) @@ -158,9 +157,11 @@ py_library( visibility = ["//visibility:public"], ) -is_python_config_setting( +config_setting( name = "is_python_3.10_linux_ppc", - python_version = "3.10", + flag_values = { + "@rules_python//python/config_settings:python_version_major_minor": "3.10", + }, constraint_values = [ "@platforms//cpu:ppc", "@platforms//os:linux", @@ -168,16 +169,20 @@ is_python_config_setting( visibility = ["//visibility:private"], ) -is_python_config_setting( +config_setting( name = "is_python_3.9_anyos_aarch64", - python_version = "3.9", + flag_values = { + "@rules_python//python/config_settings:python_version_major_minor": "3.9", + }, constraint_values = ["@platforms//cpu:aarch64"], visibility = ["//visibility:private"], ) -is_python_config_setting( +config_setting( name = "is_python_3.9_linux_anyarch", - python_version = "3.9", + flag_values = { + "@rules_python//python/config_settings:python_version_major_minor": "3.9", + }, constraint_values = ["@platforms//os:linux"], visibility = ["//visibility:private"], ) From b8df9758c6beb8bb8b536a9ebba500e1a8f45dd2 Mon Sep 17 00:00:00 2001 From: aignas <240938+aignas@users.noreply.github.com> Date: Tue, 17 Sep 2024 10:40:42 +0900 Subject: [PATCH 3/8] chore: pre-commit run update-bzlmod-lockfiles -a --- examples/bzlmod/MODULE.bazel.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/bzlmod/MODULE.bazel.lock b/examples/bzlmod/MODULE.bazel.lock index 1be965faed..37becb6141 100644 --- a/examples/bzlmod/MODULE.bazel.lock +++ b/examples/bzlmod/MODULE.bazel.lock @@ -1231,7 +1231,7 @@ }, "@@rules_python~//python/extensions:pip.bzl%pip": { "general": { - "bzlTransitiveDigest": "3vqCp6yUy32HDgpZG9L+zqedcsEnHZu0Y7hfoRk3owY=", + "bzlTransitiveDigest": "QwtZh6Z/xzfVDRNoLrjoY4WpKkjU6vzi86SSz1Gk5L0=", "usagesDigest": "MChlcSw99EuW3K7OOoMcXQIdcJnEh6YmfyjJm+9mxIg=", "recordedFileInputs": { "@@other_module~//requirements_lock_3_11.txt": "a7d0061366569043d5efcf80e34a32c732679367cb3c831c4cdc606adc36d314", @@ -6145,7 +6145,7 @@ }, "@@rules_python~//python/private/pypi:pip.bzl%pip_internal": { "general": { - "bzlTransitiveDigest": "DdkE6u15ketmEdOGiZ1UcHX7sZV/xpVbFQLWBKjOAYM=", + "bzlTransitiveDigest": "qYNXwIEgNRI+laE7LWohOQaRd4OvtwgcOpPPrrqXVHc=", "usagesDigest": "Y8ihY+R57BAFhalrVLVdJFrpwlbsiKz9JPJ99ljF7HA=", "recordedFileInputs": { "@@rules_python~//tools/publish/requirements.txt": "031e35d03dde03ae6305fe4b3d1f58ad7bdad857379752deede0f93649991b8a", From 278341532858e2be0f4ad660b562e67c9ff66a2d Mon Sep 17 00:00:00 2001 From: aignas <240938+aignas@users.noreply.github.com> Date: Tue, 17 Sep 2024 10:50:41 +0900 Subject: [PATCH 4/8] wip --- CHANGELOG.md | 11 +---------- MODULE.bazel | 8 -------- examples/bzlmod/MODULE.bazel.lock | 14 ++------------ python/private/config_settings.bzl | 8 ++++---- 4 files changed, 7 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 064663110b..7207b30be0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -78,16 +78,7 @@ A brief description of the categories of changes: ### Removed * (toolchains): Removed accidentally exposed `http_archive` symbol from `python/repositories.bzl`. -* (toolchains): An internal _is_python_config_setting_ has been removed - from rules_python as it can now be replaced by: - ```starlark - native.config_setting( - name = "my_config_setting", - flag_values = { - "@rules_python//python/config_settings:python_version_major_minor": "3.11", - }, - ) - ``` +* (toolchains): An internal _is_python_config_setting_ macro has been removed. ## [0.35.0] - 2024-08-15 diff --git a/MODULE.bazel b/MODULE.bazel index 80915eb1de..9ac3e7a04c 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -46,9 +46,6 @@ python.toolchain( is_default = True, python_version = "3.11", ) -python.toolchain( - python_version = "3.12", -) use_repo(python, "python_3_11", "python_versions", "pythons_hub") # This call registers the Python toolchains. @@ -98,11 +95,6 @@ dev_pip.parse( python_version = "3.11", requirements_lock = "//docs:requirements.txt", ) -dev_pip.parse( - hub_name = "dev_pip", - python_version = "3.12", - requirements_lock = "//docs:requirements.txt", -) dev_pip.parse( hub_name = "pypiserver", python_version = "3.11", diff --git a/examples/bzlmod/MODULE.bazel.lock b/examples/bzlmod/MODULE.bazel.lock index 37becb6141..5d1e334e24 100644 --- a/examples/bzlmod/MODULE.bazel.lock +++ b/examples/bzlmod/MODULE.bazel.lock @@ -1231,7 +1231,7 @@ }, "@@rules_python~//python/extensions:pip.bzl%pip": { "general": { - "bzlTransitiveDigest": "QwtZh6Z/xzfVDRNoLrjoY4WpKkjU6vzi86SSz1Gk5L0=", + "bzlTransitiveDigest": "2VyEEWFxnt+bKIYzDTLApfa1ruWFN2PSrU0ASgHpVX4=", "usagesDigest": "MChlcSw99EuW3K7OOoMcXQIdcJnEh6YmfyjJm+9mxIg=", "recordedFileInputs": { "@@other_module~//requirements_lock_3_11.txt": "a7d0061366569043d5efcf80e34a32c732679367cb3c831c4cdc606adc36d314", @@ -6130,11 +6130,6 @@ "python_3_11_host", "rules_python~~python~python_3_11_host" ], - [ - "rules_python~~python~pythons_hub", - "python_3_12_host", - "rules_python~~python~python_3_12_host" - ], [ "rules_python~~python~pythons_hub", "python_3_9_host", @@ -6145,7 +6140,7 @@ }, "@@rules_python~//python/private/pypi:pip.bzl%pip_internal": { "general": { - "bzlTransitiveDigest": "qYNXwIEgNRI+laE7LWohOQaRd4OvtwgcOpPPrrqXVHc=", + "bzlTransitiveDigest": "sjx3oJrySkMSqUieTM+5mcv4iP+ObUZBE8FUj2PAdSs=", "usagesDigest": "Y8ihY+R57BAFhalrVLVdJFrpwlbsiKz9JPJ99ljF7HA=", "recordedFileInputs": { "@@rules_python~//tools/publish/requirements.txt": "031e35d03dde03ae6305fe4b3d1f58ad7bdad857379752deede0f93649991b8a", @@ -8392,11 +8387,6 @@ "python_3_11_host", "rules_python~~python~python_3_11_host" ], - [ - "rules_python~~python~pythons_hub", - "python_3_12_host", - "rules_python~~python~python_3_12_host" - ], [ "rules_python~~python~pythons_hub", "python_3_9_host", diff --git a/python/private/config_settings.bzl b/python/private/config_settings.bzl index c42803fba6..3e086bf390 100644 --- a/python/private/config_settings.bzl +++ b/python/private/config_settings.bzl @@ -20,8 +20,8 @@ load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo") load("//python:versions.bzl", "MINOR_MAPPING", "TOOL_VERSIONS") load(":semver.bzl", "semver") -_PYTHON_VERSION_FLAG = str(Label("//python/config_settings:python_version")) -_PYTHON_MINOR_VERSION_FLAG = str(Label("//python/config_settings:python_version_major_minor")) +_PYTHON_VERSION_FLAG = Label("//python/config_settings:python_version") +_PYTHON_MAJOR_MINOR_VERSION_FLAG = Label("//python/config_settings:_python_major_minor_version") def construct_config_settings(name = None): # buildifier: disable=function-docstring """Create a 'python_version' config flag and construct all config settings used in rules_python. @@ -43,7 +43,7 @@ def construct_config_settings(name = None): # buildifier: disable=function-docs ) _python_major_minor( - name = "python_version_major_minor", + name = _PYTHON_MAJOR_MINOR_VERSION_FLAG.name, build_setting_default = "", visibility = ["//visibility:public"], ) @@ -61,7 +61,7 @@ def construct_config_settings(name = None): # buildifier: disable=function-docs for minor in range(20): native.config_setting( name = "is_python_3.{}".format(minor), - flag_values = {_PYTHON_MINOR_VERSION_FLAG: "3.{}".format(minor)}, + flag_values = {_PYTHON_MAJOR_MINOR_VERSION_FLAG: "3.{}".format(minor)}, visibility = ["//visibility:public"], ) From 7858cd89eb61e334a2c2c2d13c66b31a731b7830 Mon Sep 17 00:00:00 2001 From: aignas <240938+aignas@users.noreply.github.com> Date: Tue, 17 Sep 2024 11:04:42 +0900 Subject: [PATCH 5/8] cleanup the config settings implementation and mark the types as internal --- python/config_settings/BUILD.bazel | 3 ++ python/private/BUILD.bazel | 3 +- python/private/config_settings.bzl | 47 +++++++++++++++++------------- 3 files changed, 31 insertions(+), 22 deletions(-) diff --git a/python/config_settings/BUILD.bazel b/python/config_settings/BUILD.bazel index 20bc50660a..c31d69f202 100644 --- a/python/config_settings/BUILD.bazel +++ b/python/config_settings/BUILD.bazel @@ -1,4 +1,5 @@ load("@bazel_skylib//rules:common_settings.bzl", "string_flag") +load("//python:versions.bzl", "MINOR_MAPPING", "TOOL_VERSIONS") load( "//python/private:flags.bzl", "BootstrapImplFlag", @@ -27,6 +28,8 @@ filegroup( construct_config_settings( name = "construct_config_settings", + minor_mapping = MINOR_MAPPING, + versions = TOOL_VERSIONS.keys(), ) string_flag( diff --git a/python/private/BUILD.bazel b/python/private/BUILD.bazel index a35e2f7c2e..ab0604d53f 100644 --- a/python/private/BUILD.bazel +++ b/python/private/BUILD.bazel @@ -78,8 +78,9 @@ bzl_library( name = "config_settings_bzl", srcs = ["config_settings.bzl"], deps = [ - "//python:versions_bzl", + ":semver_bzl", "@bazel_skylib//lib:selects", + "@bazel_skylib//rules:common_settings", ], ) diff --git a/python/private/config_settings.bzl b/python/private/config_settings.bzl index 3e086bf390..eec6ed7c89 100644 --- a/python/private/config_settings.bzl +++ b/python/private/config_settings.bzl @@ -17,23 +17,25 @@ load("@bazel_skylib//lib:selects.bzl", "selects") load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo") -load("//python:versions.bzl", "MINOR_MAPPING", "TOOL_VERSIONS") load(":semver.bzl", "semver") _PYTHON_VERSION_FLAG = Label("//python/config_settings:python_version") _PYTHON_MAJOR_MINOR_VERSION_FLAG = Label("//python/config_settings:_python_major_minor_version") -def construct_config_settings(name = None): # buildifier: disable=function-docstring +def construct_config_settings(*, name, versions, minor_mapping): # buildifier: disable=function-docstring """Create a 'python_version' config flag and construct all config settings used in rules_python. This mainly includes the targets that are used in the toolchain and pip hub repositories that only match on the 'python_version' flag values. Args: - name(str): A dummy name value that is no-op for now. + name: {type}`str` A dummy name value that is no-op for now. + versions: {type}`list[str]` A list of versions to build constraint settings for. + minor_mapping: {type}`dict[str, str]` A mapping from `X.Y` to `X.Y.Z` python versions. """ + _ = name # @unused _python_version_flag( - name = "python_version", + name = _PYTHON_VERSION_FLAG.name, # TODO: The default here should somehow match the MODULE config. Until # then, use the empty string to indicate an unknown version. This # also prevents version-unaware targets from inadvertently matching @@ -42,7 +44,7 @@ def construct_config_settings(name = None): # buildifier: disable=function-docs visibility = ["//visibility:public"], ) - _python_major_minor( + _python_version_major_minor_flag( name = _PYTHON_MAJOR_MINOR_VERSION_FLAG.name, build_setting_default = "", visibility = ["//visibility:public"], @@ -54,20 +56,12 @@ def construct_config_settings(name = None): # buildifier: disable=function-docs visibility = ["//visibility:public"], ) - # This matches the raw flag value, e.g. --//python/config_settings:python_version=3.8 - # It's private because matching the concept of e.g. "3.8" value is done - # using the `is_python_X.Y` config setting group, which is aware of the - # minor versions that could match instead. - for minor in range(20): - native.config_setting( - name = "is_python_3.{}".format(minor), - flag_values = {_PYTHON_MAJOR_MINOR_VERSION_FLAG: "3.{}".format(minor)}, - visibility = ["//visibility:public"], - ) - - for version in TOOL_VERSIONS.keys(): + minor_versions = {} + for version in versions: minor_version, _, _ = version.rpartition(".") - if MINOR_MAPPING[minor_version] != version: + minor_versions[minor_version] = None + + if minor_mapping[minor_version] != version: native.config_setting( name = "is_python_{}".format(version), flag_values = {":python_version": version}, @@ -101,6 +95,17 @@ def construct_config_settings(name = None): # buildifier: disable=function-docs visibility = ["//visibility:public"], ) + # This matches the raw flag value, e.g. --//python/config_settings:python_version=3.8 + # It's private because matching the concept of e.g. "3.8" value is done + # using the `is_python_X.Y` config setting group, which is aware of the + # minor versions that could match instead. + for minor in minor_versions: + native.config_setting( + name = "is_python_{}".format(minor), + flag_values = {_PYTHON_MAJOR_MINOR_VERSION_FLAG: minor}, + visibility = ["//visibility:public"], + ) + def _python_version_flag_impl(ctx): value = ctx.build_setting_value return [ @@ -121,7 +126,7 @@ _python_version_flag = rule( attrs = {}, ) -def _python_major_minor_impl(ctx): +def _python_version_major_minor_flag_impl(ctx): input = ctx.attr._python_version_flag[config_common.FeatureFlagInfo].value if input: version = semver(input) @@ -131,8 +136,8 @@ def _python_major_minor_impl(ctx): return [config_common.FeatureFlagInfo(value = value)] -_python_major_minor = rule( - implementation = _python_major_minor_impl, +_python_version_major_minor_flag = rule( + implementation = _python_version_major_minor_flag_impl, build_setting = config.string(flag = False), attrs = { "_python_version_flag": attr.label( From 134fd0aec1097e5ae6d0d7bd6e3de3df75820922 Mon Sep 17 00:00:00 2001 From: aignas <240938+aignas@users.noreply.github.com> Date: Tue, 17 Sep 2024 11:07:28 +0900 Subject: [PATCH 6/8] fixup! cleanup the config settings implementation and mark the types as internal --- python/private/config_settings.bzl | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/python/private/config_settings.bzl b/python/private/config_settings.bzl index eec6ed7c89..8753336693 100644 --- a/python/private/config_settings.bzl +++ b/python/private/config_settings.bzl @@ -56,12 +56,10 @@ def construct_config_settings(*, name, versions, minor_mapping): # buildifier: visibility = ["//visibility:public"], ) - minor_versions = {} + _reverse_minor_mapping = {full: minor for minor, full in minor_mapping.items()} for version in versions: - minor_version, _, _ = version.rpartition(".") - minor_versions[minor_version] = None - - if minor_mapping[minor_version] != version: + minor_version = _reverse_minor_mapping.get(version) + if not minor_version: native.config_setting( name = "is_python_{}".format(version), flag_values = {":python_version": version}, From 5793274fef469bb139e0e33944c6a5d81f3d6ad6 Mon Sep 17 00:00:00 2001 From: aignas <240938+aignas@users.noreply.github.com> Date: Tue, 17 Sep 2024 11:15:08 +0900 Subject: [PATCH 7/8] fixup! fixup! cleanup the config settings implementation and mark the types as internal --- python/private/config_settings.bzl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/private/config_settings.bzl b/python/private/config_settings.bzl index 8753336693..f51dd20204 100644 --- a/python/private/config_settings.bzl +++ b/python/private/config_settings.bzl @@ -97,7 +97,7 @@ def construct_config_settings(*, name, versions, minor_mapping): # buildifier: # It's private because matching the concept of e.g. "3.8" value is done # using the `is_python_X.Y` config setting group, which is aware of the # minor versions that could match instead. - for minor in minor_versions: + for minor in minor_mapping.keys(): native.config_setting( name = "is_python_{}".format(minor), flag_values = {_PYTHON_MAJOR_MINOR_VERSION_FLAG: minor}, From 1919e62ae46168202218ed1e9d978c534f38e46e Mon Sep 17 00:00:00 2001 From: aignas <240938+aignas@users.noreply.github.com> Date: Tue, 17 Sep 2024 11:50:09 +0900 Subject: [PATCH 8/8] fixup! fixup! fixup! cleanup the config settings implementation and mark the types as internal --- examples/bzlmod/MODULE.bazel.lock | 4 ++-- python/private/config_settings.bzl | 6 +++--- python/private/pypi/generate_whl_library_build_bazel.bzl | 2 +- tests/config_settings/construct_config_settings_tests.bzl | 6 +++--- .../generate_whl_library_build_bazel_tests.bzl | 6 +++--- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/examples/bzlmod/MODULE.bazel.lock b/examples/bzlmod/MODULE.bazel.lock index 5d1e334e24..f0144e82e0 100644 --- a/examples/bzlmod/MODULE.bazel.lock +++ b/examples/bzlmod/MODULE.bazel.lock @@ -1231,7 +1231,7 @@ }, "@@rules_python~//python/extensions:pip.bzl%pip": { "general": { - "bzlTransitiveDigest": "2VyEEWFxnt+bKIYzDTLApfa1ruWFN2PSrU0ASgHpVX4=", + "bzlTransitiveDigest": "jb9c5l3dvSB2MHd/zfkT8Yr8efvg+K/YHtiRHU3aU6o=", "usagesDigest": "MChlcSw99EuW3K7OOoMcXQIdcJnEh6YmfyjJm+9mxIg=", "recordedFileInputs": { "@@other_module~//requirements_lock_3_11.txt": "a7d0061366569043d5efcf80e34a32c732679367cb3c831c4cdc606adc36d314", @@ -6140,7 +6140,7 @@ }, "@@rules_python~//python/private/pypi:pip.bzl%pip_internal": { "general": { - "bzlTransitiveDigest": "sjx3oJrySkMSqUieTM+5mcv4iP+ObUZBE8FUj2PAdSs=", + "bzlTransitiveDigest": "cLqaqCEOdhle6//lX1Kcs2hfkmSerh2fk0izwhV8/GU=", "usagesDigest": "Y8ihY+R57BAFhalrVLVdJFrpwlbsiKz9JPJ99ljF7HA=", "recordedFileInputs": { "@@rules_python~//tools/publish/requirements.txt": "031e35d03dde03ae6305fe4b3d1f58ad7bdad857379752deede0f93649991b8a", diff --git a/python/private/config_settings.bzl b/python/private/config_settings.bzl index f51dd20204..b15d6a8e03 100644 --- a/python/private/config_settings.bzl +++ b/python/private/config_settings.bzl @@ -20,7 +20,7 @@ load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo") load(":semver.bzl", "semver") _PYTHON_VERSION_FLAG = Label("//python/config_settings:python_version") -_PYTHON_MAJOR_MINOR_VERSION_FLAG = Label("//python/config_settings:_python_major_minor_version") +_PYTHON_VERSION_MAJOR_MINOR_FLAG = Label("//python/config_settings:_python_version_major_minor") def construct_config_settings(*, name, versions, minor_mapping): # buildifier: disable=function-docstring """Create a 'python_version' config flag and construct all config settings used in rules_python. @@ -45,7 +45,7 @@ def construct_config_settings(*, name, versions, minor_mapping): # buildifier: ) _python_version_major_minor_flag( - name = _PYTHON_MAJOR_MINOR_VERSION_FLAG.name, + name = _PYTHON_VERSION_MAJOR_MINOR_FLAG.name, build_setting_default = "", visibility = ["//visibility:public"], ) @@ -100,7 +100,7 @@ def construct_config_settings(*, name, versions, minor_mapping): # buildifier: for minor in minor_mapping.keys(): native.config_setting( name = "is_python_{}".format(minor), - flag_values = {_PYTHON_MAJOR_MINOR_VERSION_FLAG: minor}, + flag_values = {_PYTHON_VERSION_MAJOR_MINOR_FLAG: minor}, visibility = ["//visibility:public"], ) diff --git a/python/private/pypi/generate_whl_library_build_bazel.bzl b/python/private/pypi/generate_whl_library_build_bazel.bzl index 934fa00c69..0be6f9c409 100644 --- a/python/private/pypi/generate_whl_library_build_bazel.bzl +++ b/python/private/pypi/generate_whl_library_build_bazel.bzl @@ -162,7 +162,7 @@ def _render_config_settings(dependencies_by_platform): config_setting( name = "is_{name}", flag_values = {{ - "@rules_python//python/config_settings:python_version_major_minor": "3.{minor_version}", + "@rules_python//python/config_settings:_python_version_major_minor": "3.{minor_version}", }}, constraint_values = {constraint_values}, visibility = ["//visibility:private"], diff --git a/tests/config_settings/construct_config_settings_tests.bzl b/tests/config_settings/construct_config_settings_tests.bzl index 1e505a7232..9e6b6e1fc3 100644 --- a/tests/config_settings/construct_config_settings_tests.bzl +++ b/tests/config_settings/construct_config_settings_tests.bzl @@ -167,7 +167,7 @@ def construct_config_settings_test_suite(name): # buildifier: disable=function- "@platforms//os:" + os, ], flag_values = { - "//python/config_settings:python_version_major_minor": "3.11", + "//python/config_settings:_python_version_major_minor": "3.11", }, ) @@ -178,7 +178,7 @@ def construct_config_settings_test_suite(name): # buildifier: disable=function- "@platforms//cpu:" + cpu, ], flag_values = { - "//python/config_settings:python_version_major_minor": "3.11", + "//python/config_settings:_python_version_major_minor": "3.11", }, ) @@ -198,7 +198,7 @@ def construct_config_settings_test_suite(name): # buildifier: disable=function- "@platforms//os:" + os, ], flag_values = { - "//python/config_settings:python_version_major_minor": "3.11", + "//python/config_settings:_python_version_major_minor": "3.11", }, ) diff --git a/tests/pypi/generate_whl_library_build_bazel/generate_whl_library_build_bazel_tests.bzl b/tests/pypi/generate_whl_library_build_bazel/generate_whl_library_build_bazel_tests.bzl index 94530117cd..a860681ae9 100644 --- a/tests/pypi/generate_whl_library_build_bazel/generate_whl_library_build_bazel_tests.bzl +++ b/tests/pypi/generate_whl_library_build_bazel/generate_whl_library_build_bazel_tests.bzl @@ -160,7 +160,7 @@ py_library( config_setting( name = "is_python_3.10_linux_ppc", flag_values = { - "@rules_python//python/config_settings:python_version_major_minor": "3.10", + "@rules_python//python/config_settings:_python_version_major_minor": "3.10", }, constraint_values = [ "@platforms//cpu:ppc", @@ -172,7 +172,7 @@ config_setting( config_setting( name = "is_python_3.9_anyos_aarch64", flag_values = { - "@rules_python//python/config_settings:python_version_major_minor": "3.9", + "@rules_python//python/config_settings:_python_version_major_minor": "3.9", }, constraint_values = ["@platforms//cpu:aarch64"], visibility = ["//visibility:private"], @@ -181,7 +181,7 @@ config_setting( config_setting( name = "is_python_3.9_linux_anyarch", flag_values = { - "@rules_python//python/config_settings:python_version_major_minor": "3.9", + "@rules_python//python/config_settings:_python_version_major_minor": "3.9", }, constraint_values = ["@platforms//os:linux"], visibility = ["//visibility:private"],