diff --git a/examples/bzlmod/MODULE.bazel.lock b/examples/bzlmod/MODULE.bazel.lock index f0144e82e0..234dc46cab 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": "jb9c5l3dvSB2MHd/zfkT8Yr8efvg+K/YHtiRHU3aU6o=", + "bzlTransitiveDigest": "Cca+OPIA5xqQl5ND8j44y5jBkjQfz+36h8Hgq0N26I0=", "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": "cLqaqCEOdhle6//lX1Kcs2hfkmSerh2fk0izwhV8/GU=", + "bzlTransitiveDigest": "wkQNgti5fKONsAUn77ZyTWdfaJfI2cSDrSI0b4JzmI8=", "usagesDigest": "Y8ihY+R57BAFhalrVLVdJFrpwlbsiKz9JPJ99ljF7HA=", "recordedFileInputs": { "@@rules_python~//tools/publish/requirements.txt": "031e35d03dde03ae6305fe4b3d1f58ad7bdad857379752deede0f93649991b8a", diff --git a/python/BUILD.bazel b/python/BUILD.bazel index 6fcde3892d..b7a2172df5 100644 --- a/python/BUILD.bazel +++ b/python/BUILD.bazel @@ -229,7 +229,11 @@ bzl_library( name = "repositories_bzl", srcs = ["repositories.bzl"], deps = [ - "//python/private:python_repositories_bzl", + "//python/private:is_standalone_interpreter_bzl", + "//python/private:py_repositories_bzl", + "//python/private:python_register_multi_toolchains_bzl", + "//python/private:python_register_toolchains_bzl", + "//python/private:python_repository_bzl", ], ) diff --git a/python/private/BUILD.bazel b/python/private/BUILD.bazel index 1e05b928bc..5fa551454e 100644 --- a/python/private/BUILD.bazel +++ b/python/private/BUILD.bazel @@ -123,6 +123,14 @@ bzl_library( deps = [":bzlmod_enabled_bzl"], ) +bzl_library( + name = "is_standalone_interpreter_bzl", + srcs = ["is_standalone_interpreter.bzl"], + deps = [ + ":repo_utils_bzl", + ], +) + bzl_library( name = "normalize_name_bzl", srcs = ["normalize_name.bzl"], @@ -143,22 +151,53 @@ bzl_library( ) bzl_library( - name = "python_repositories_bzl", - srcs = ["python_repositories.bzl"], + name = "py_repositories_bzl", + srcs = ["py_repositories.bzl"], + deps = [ + ":bazel_tools_bzl", + ":internal_config_repo_bzl", + "//python/private/pypi:deps_bzl", + ], +) + +bzl_library( + name = "python_register_toolchains_bzl", + srcs = ["python_register_toolchains.bzl"], deps = [ + ":auth_bzl", + ":bazel_tools_bzl", + ":bzlmod_enabled_bzl", + ":coverage_deps_bzl", + ":full_version_bzl", + ":internal_config_repo_bzl", + ":python_repository_bzl", + ":toolchains_repo_bzl", "//python:versions_bzl", - "//python/private:auth_bzl", - "//python/private:bazel_tools_bzl", - "//python/private:bzlmod_enabled_bzl", - "//python/private:coverage_deps_bzl", - "//python/private:full_version_bzl", - "//python/private:internal_config_repo_bzl", - "//python/private:repo_utils_bzl", - "//python/private:toolchains_repo_bzl", "//python/private/pypi:deps_bzl", ], ) +bzl_library( + name = "python_repository_bzl", + srcs = ["python_repository.bzl"], + deps = [ + ":auth_bzl", + ":repo_utils_bzl", + ":text_util_bzl", + "//python:versions_bzl", + ], +) + +bzl_library( + name = "python_register_multi_toolchains_bzl", + srcs = ["python_register_multi_toolchains.bzl"], + deps = [ + ":python_register_toolchains_bzl", + ":toolchains_repo_bzl", + "//python:versions_bzl", + ], +) + bzl_library( name = "pythons_hub_bzl", srcs = ["pythons_hub.bzl"], diff --git a/python/private/is_standalone_interpreter.bzl b/python/private/is_standalone_interpreter.bzl new file mode 100644 index 0000000000..5da7389612 --- /dev/null +++ b/python/private/is_standalone_interpreter.bzl @@ -0,0 +1,50 @@ +# Copyright 2024 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""This file contains repository rules and macros to support toolchain registration. +""" + +load(":repo_utils.bzl", "repo_utils") + +STANDALONE_INTERPRETER_FILENAME = "STANDALONE_INTERPRETER" + +def is_standalone_interpreter(rctx, python_interpreter_path, *, logger = None): + """Query a python interpreter target for whether or not it's a rules_rust provided toolchain + + Args: + rctx: {type}`repository_ctx` The repository rule's context object. + python_interpreter_path: {type}`path` A path representing the interpreter. + logger: Optional logger to use for operations. + + Returns: + {type}`bool` Whether or not the target is from a rules_python generated toolchain. + """ + + # Only update the location when using a hermetic toolchain. + if not python_interpreter_path: + return False + + # This is a rules_python provided toolchain. + return repo_utils.execute_unchecked( + rctx, + op = "IsStandaloneInterpreter", + arguments = [ + "ls", + "{}/{}".format( + python_interpreter_path.dirname, + STANDALONE_INTERPRETER_FILENAME, + ), + ], + logger = logger, + ).return_code == 0 diff --git a/python/private/py_repositories.bzl b/python/private/py_repositories.bzl new file mode 100644 index 0000000000..ace3750a2b --- /dev/null +++ b/python/private/py_repositories.bzl @@ -0,0 +1,49 @@ +# Copyright 2024 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""This file contains macros to be called during WORKSPACE evaluation.""" + +load("@bazel_tools//tools/build_defs/repo:http.bzl", _http_archive = "http_archive") +load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe") +load("//python/private/pypi:deps.bzl", "pypi_deps") +load(":internal_config_repo.bzl", "internal_config_repo") + +def http_archive(**kwargs): + maybe(_http_archive, **kwargs) + +def py_repositories(): + """Runtime dependencies that users must install. + + This function should be loaded and called in the user's WORKSPACE. + With bzlmod enabled, this function is not needed since MODULE.bazel handles transitive deps. + """ + maybe( + internal_config_repo, + name = "rules_python_internal", + ) + http_archive( + name = "bazel_skylib", + sha256 = "74d544d96f4a5bb630d465ca8bbcfe231e3594e5aae57e1edbf17a6eb3ca2506", + urls = [ + "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.3.0/bazel-skylib-1.3.0.tar.gz", + "https://github.com/bazelbuild/bazel-skylib/releases/download/1.3.0/bazel-skylib-1.3.0.tar.gz", + ], + ) + http_archive( + name = "rules_cc", + urls = ["https://github.com/bazelbuild/rules_cc/releases/download/0.0.9/rules_cc-0.0.9.tar.gz"], + sha256 = "2037875b9a4456dce4a79d112a8ae885bbc4aad968e6587dca6e64f3a0900cdf", + strip_prefix = "rules_cc-0.0.9", + ) + pypi_deps() diff --git a/python/private/pypi/BUILD.bazel b/python/private/pypi/BUILD.bazel index 1db50af7c7..2b25bfbfb4 100644 --- a/python/private/pypi/BUILD.bazel +++ b/python/private/pypi/BUILD.bazel @@ -306,9 +306,9 @@ bzl_library( ":patch_whl_bzl", ":pypi_repo_utils_bzl", ":whl_target_platforms_bzl", - "//python:repositories_bzl", "//python/private:auth_bzl", "//python/private:envsubst_bzl", + "//python/private:is_standalone_interpreter_bzl", "//python/private:repo_utils_bzl", ], ) diff --git a/python/private/pypi/whl_library.bzl b/python/private/pypi/whl_library.bzl index 5b14151be6..309316b2ee 100644 --- a/python/private/pypi/whl_library.bzl +++ b/python/private/pypi/whl_library.bzl @@ -16,7 +16,7 @@ load("//python/private:auth.bzl", "AUTH_ATTRS", "get_auth") load("//python/private:envsubst.bzl", "envsubst") -load("//python/private:python_repositories.bzl", "is_standalone_interpreter") +load("//python/private:is_standalone_interpreter.bzl", "is_standalone_interpreter") load("//python/private:repo_utils.bzl", "REPO_DEBUG_ENV_VAR", "repo_utils") load(":attrs.bzl", "ATTRS", "use_isolated") load(":deps.bzl", "all_repo_names") diff --git a/python/private/python.bzl b/python/private/python.bzl index 9a9a240cb3..98b089f7ca 100644 --- a/python/private/python.bzl +++ b/python/private/python.bzl @@ -15,9 +15,9 @@ "Python toolchain module extensions for use with bzlmod" load("@bazel_features//:features.bzl", "bazel_features") -load("//python:repositories.bzl", "python_register_toolchains") load("//python:versions.bzl", "MINOR_MAPPING", "TOOL_VERSIONS") load(":full_version.bzl", "full_version") +load(":python_register_toolchains.bzl", "python_register_toolchains") load(":pythons_hub.bzl", "hub_repo") load(":repo_utils.bzl", "repo_utils") load(":text_util.bzl", "render") diff --git a/python/private/python_register_multi_toolchains.bzl b/python/private/python_register_multi_toolchains.bzl new file mode 100644 index 0000000000..68f5249350 --- /dev/null +++ b/python/private/python_register_multi_toolchains.bzl @@ -0,0 +1,75 @@ +# Copyright 2024 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""This file contains repository rules and macros to support toolchain registration. +""" + +load("//python:versions.bzl", "MINOR_MAPPING") +load(":python_register_toolchains.bzl", "python_register_toolchains") +load(":toolchains_repo.bzl", "multi_toolchain_aliases") + +def python_register_multi_toolchains( + name, + python_versions, + default_version = None, + minor_mapping = None, + **kwargs): + """Convenience macro for registering multiple Python toolchains. + + Args: + name: {type}`str` base name for each name in {obj}`python_register_toolchains` call. + python_versions: {type}`list[str]` the Python versions. + default_version: {type}`str` the default Python version. If not set, + the first version in python_versions is used. + minor_mapping: {type}`dict[str, str]` mapping between `X.Y` to `X.Y.Z` + format. Defaults to the value in `//python:versions.bzl`. + **kwargs: passed to each {obj}`python_register_toolchains` call. + """ + if len(python_versions) == 0: + fail("python_versions must not be empty") + + minor_mapping = minor_mapping or MINOR_MAPPING + + if not default_version: + default_version = python_versions.pop(0) + for python_version in python_versions: + if python_version == default_version: + # We register the default version lastly so that it's not picked first when --platforms + # is set with a constraint during toolchain resolution. This is due to the fact that + # Bazel will match the unconstrained toolchain if we register it before the constrained + # ones. + continue + python_register_toolchains( + name = name + "_" + python_version.replace(".", "_"), + python_version = python_version, + set_python_version_constraint = True, + minor_mapping = minor_mapping, + **kwargs + ) + python_register_toolchains( + name = name + "_" + default_version.replace(".", "_"), + python_version = default_version, + set_python_version_constraint = False, + minor_mapping = minor_mapping, + **kwargs + ) + + multi_toolchain_aliases( + name = name, + python_versions = { + python_version: name + "_" + python_version.replace(".", "_") + for python_version in (python_versions + [default_version]) + }, + minor_mapping = minor_mapping, + ) diff --git a/python/private/python_register_toolchains.bzl b/python/private/python_register_toolchains.bzl new file mode 100644 index 0000000000..7638d76313 --- /dev/null +++ b/python/private/python_register_toolchains.bzl @@ -0,0 +1,176 @@ +# Copyright 2024 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""This file contains repository rules and macros to support toolchain registration. +""" + +load( + "//python:versions.bzl", + "DEFAULT_RELEASE_BASE_URL", + "MINOR_MAPPING", + "PLATFORMS", + "TOOL_VERSIONS", + "get_release_info", +) +load(":bzlmod_enabled.bzl", "BZLMOD_ENABLED") +load(":coverage_deps.bzl", "coverage_dep") +load(":full_version.bzl", "full_version") +load(":python_repository.bzl", "python_repository") +load( + ":toolchains_repo.bzl", + "host_toolchain", + "toolchain_aliases", + "toolchains_repo", +) + +# Wrapper macro around everything above, this is the primary API. +def python_register_toolchains( + name, + python_version, + register_toolchains = True, + register_coverage_tool = False, + set_python_version_constraint = False, + tool_versions = None, + minor_mapping = None, + **kwargs): + """Convenience macro for users which does typical setup. + + - Create a repository for each built-in platform like "python_3_8_linux_amd64" - + this repository is lazily fetched when Python is needed for that platform. + - Create a repository exposing toolchains for each platform like + "python_platforms". + - Register a toolchain pointing at each platform. + + Users can avoid this macro and do these steps themselves, if they want more + control. + + Args: + name: {type}`str` base name for all created repos, e.g. "python_3_8". + python_version: {type}`str` the Python version. + register_toolchains: {type}`bool` Whether or not to register the downloaded toolchains. + register_coverage_tool: {type}`bool` Whether or not to register the + downloaded coverage tool to the toolchains. + set_python_version_constraint: {type}`bool` When set to `True`, + `target_compatible_with` for the toolchains will include a version + constraint. + tool_versions: {type}`dict` contains a mapping of version with SHASUM + and platform info. If not supplied, the defaults in + python/versions.bzl will be used. + minor_mapping: {type}`dict[str, str]` contains a mapping from `X.Y` to `X.Y.Z` + version. + **kwargs: passed to each {obj}`python_repository` call. + """ + + if BZLMOD_ENABLED: + # you cannot used native.register_toolchains when using bzlmod. + register_toolchains = False + + base_url = kwargs.pop("base_url", DEFAULT_RELEASE_BASE_URL) + tool_versions = tool_versions or TOOL_VERSIONS + minor_mapping = minor_mapping or MINOR_MAPPING + + python_version = full_version(version = python_version, minor_mapping = minor_mapping) + + toolchain_repo_name = "{name}_toolchains".format(name = name) + + # When using unreleased Bazel versions, the version is an empty string + if native.bazel_version: + bazel_major = int(native.bazel_version.split(".")[0]) + if bazel_major < 6: + if register_coverage_tool: + # buildifier: disable=print + print(( + "WARNING: ignoring register_coverage_tool=True when " + + "registering @{name}: Bazel 6+ required, got {version}" + ).format( + name = name, + version = native.bazel_version, + )) + register_coverage_tool = False + + loaded_platforms = [] + for platform in PLATFORMS.keys(): + sha256 = tool_versions[python_version]["sha256"].get(platform, None) + if not sha256: + continue + + loaded_platforms.append(platform) + (release_filename, urls, strip_prefix, patches, patch_strip) = get_release_info(platform, python_version, base_url, tool_versions) + + # allow passing in a tool version + coverage_tool = None + coverage_tool = tool_versions[python_version].get("coverage_tool", {}).get(platform, None) + if register_coverage_tool and coverage_tool == None: + coverage_tool = coverage_dep( + name = "{name}_{platform}_coverage".format( + name = name, + platform = platform, + ), + python_version = python_version, + platform = platform, + visibility = ["@{name}_{platform}//:__subpackages__".format( + name = name, + platform = platform, + )], + ) + + python_repository( + name = "{name}_{platform}".format( + name = name, + platform = platform, + ), + sha256 = sha256, + patches = patches, + patch_strip = patch_strip, + platform = platform, + python_version = python_version, + release_filename = release_filename, + urls = urls, + strip_prefix = strip_prefix, + coverage_tool = coverage_tool, + **kwargs + ) + if register_toolchains: + native.register_toolchains("@{toolchain_repo_name}//:{platform}_toolchain".format( + toolchain_repo_name = toolchain_repo_name, + platform = platform, + )) + native.register_toolchains("@{toolchain_repo_name}//:{platform}_py_cc_toolchain".format( + toolchain_repo_name = toolchain_repo_name, + platform = platform, + )) + native.register_toolchains("@{toolchain_repo_name}//:{platform}_py_exec_tools_toolchain".format( + toolchain_repo_name = toolchain_repo_name, + platform = platform, + )) + + host_toolchain(name = name + "_host") + + toolchain_aliases( + name = name, + python_version = python_version, + user_repository_name = name, + platforms = loaded_platforms, + ) + + # in bzlmod we write out our own toolchain repos + if BZLMOD_ENABLED: + return + + toolchains_repo( + name = toolchain_repo_name, + python_version = python_version, + set_python_version_constraint = set_python_version_constraint, + user_repository_name = name, + ) diff --git a/python/private/python_repositories.bzl b/python/private/python_repository.bzl similarity index 61% rename from python/private/python_repositories.bzl rename to python/private/python_repository.bzl index 0286160b52..28a2c959dd 100644 --- a/python/private/python_repositories.bzl +++ b/python/private/python_repository.bzl @@ -1,4 +1,4 @@ -# Copyright 2022 The Bazel Authors. All rights reserved. +# Copyright 2024 The Bazel Authors. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,69 +12,13 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""This file contains macros to be called during WORKSPACE evaluation. - -For historic reasons, pip_repositories() is defined in //python:pip.bzl. +"""This file contains repository rules and macros to support toolchain registration. """ -load("@bazel_tools//tools/build_defs/repo:http.bzl", _http_archive = "http_archive") -load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe") -load( - "//python:versions.bzl", - "DEFAULT_RELEASE_BASE_URL", - "MINOR_MAPPING", - "PLATFORMS", - "TOOL_VERSIONS", - "get_release_info", -) -load("//python/private/pypi:deps.bzl", "pypi_deps") +load("//python:versions.bzl", "PLATFORMS") load(":auth.bzl", "get_auth") -load(":bzlmod_enabled.bzl", "BZLMOD_ENABLED") -load(":coverage_deps.bzl", "coverage_dep") -load(":full_version.bzl", "full_version") -load(":internal_config_repo.bzl", "internal_config_repo") load(":repo_utils.bzl", "REPO_DEBUG_ENV_VAR", "repo_utils") load(":text_util.bzl", "render") -load( - ":toolchains_repo.bzl", - "host_toolchain", - "multi_toolchain_aliases", - "toolchain_aliases", - "toolchains_repo", -) - -def http_archive(**kwargs): - maybe(_http_archive, **kwargs) - -def py_repositories(): - """Runtime dependencies that users must install. - - This function should be loaded and called in the user's WORKSPACE. - With bzlmod enabled, this function is not needed since MODULE.bazel handles transitive deps. - """ - maybe( - internal_config_repo, - name = "rules_python_internal", - ) - http_archive( - name = "bazel_skylib", - sha256 = "74d544d96f4a5bb630d465ca8bbcfe231e3594e5aae57e1edbf17a6eb3ca2506", - urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.3.0/bazel-skylib-1.3.0.tar.gz", - "https://github.com/bazelbuild/bazel-skylib/releases/download/1.3.0/bazel-skylib-1.3.0.tar.gz", - ], - ) - http_archive( - name = "rules_cc", - urls = ["https://github.com/bazelbuild/rules_cc/releases/download/0.0.9/rules_cc-0.0.9.tar.gz"], - sha256 = "2037875b9a4456dce4a79d112a8ae885bbc4aad968e6587dca6e64f3a0900cdf", - strip_prefix = "rules_cc-0.0.9", - ) - pypi_deps() - -######## -# Remaining content of the file is only used to support toolchains. -######## STANDALONE_INTERPRETER_FILENAME = "STANDALONE_INTERPRETER" @@ -458,199 +402,3 @@ function defaults (e.g. `single_version_override` for `MODULE.bazel` files. }, environ = [REPO_DEBUG_ENV_VAR], ) - -# Wrapper macro around everything above, this is the primary API. -def python_register_toolchains( - name, - python_version, - register_toolchains = True, - register_coverage_tool = False, - set_python_version_constraint = False, - tool_versions = None, - minor_mapping = None, - **kwargs): - """Convenience macro for users which does typical setup. - - - Create a repository for each built-in platform like "python_3_8_linux_amd64" - - this repository is lazily fetched when Python is needed for that platform. - - Create a repository exposing toolchains for each platform like - "python_platforms". - - Register a toolchain pointing at each platform. - - Users can avoid this macro and do these steps themselves, if they want more - control. - - Args: - name: {type}`str` base name for all created repos, e.g. "python_3_8". - python_version: {type}`str` the Python version. - register_toolchains: {type}`bool` Whether or not to register the downloaded toolchains. - register_coverage_tool: {type}`bool` Whether or not to register the - downloaded coverage tool to the toolchains. - set_python_version_constraint: {type}`bool` When set to `True`, - `target_compatible_with` for the toolchains will include a version - constraint. - tool_versions: {type}`dict` contains a mapping of version with SHASUM - and platform info. If not supplied, the defaults in - python/versions.bzl will be used. - minor_mapping: {type}`dict[str, str]` contains a mapping from `X.Y` to `X.Y.Z` - version. - **kwargs: passed to each {obj}`python_repository` call. - """ - - if BZLMOD_ENABLED: - # you cannot used native.register_toolchains when using bzlmod. - register_toolchains = False - - base_url = kwargs.pop("base_url", DEFAULT_RELEASE_BASE_URL) - tool_versions = tool_versions or TOOL_VERSIONS - minor_mapping = minor_mapping or MINOR_MAPPING - - python_version = full_version(version = python_version, minor_mapping = minor_mapping) - - toolchain_repo_name = "{name}_toolchains".format(name = name) - - # When using unreleased Bazel versions, the version is an empty string - if native.bazel_version: - bazel_major = int(native.bazel_version.split(".")[0]) - if bazel_major < 6: - if register_coverage_tool: - # buildifier: disable=print - print(( - "WARNING: ignoring register_coverage_tool=True when " + - "registering @{name}: Bazel 6+ required, got {version}" - ).format( - name = name, - version = native.bazel_version, - )) - register_coverage_tool = False - - loaded_platforms = [] - for platform in PLATFORMS.keys(): - sha256 = tool_versions[python_version]["sha256"].get(platform, None) - if not sha256: - continue - - loaded_platforms.append(platform) - (release_filename, urls, strip_prefix, patches, patch_strip) = get_release_info(platform, python_version, base_url, tool_versions) - - # allow passing in a tool version - coverage_tool = None - coverage_tool = tool_versions[python_version].get("coverage_tool", {}).get(platform, None) - if register_coverage_tool and coverage_tool == None: - coverage_tool = coverage_dep( - name = "{name}_{platform}_coverage".format( - name = name, - platform = platform, - ), - python_version = python_version, - platform = platform, - visibility = ["@{name}_{platform}//:__subpackages__".format( - name = name, - platform = platform, - )], - ) - - python_repository( - name = "{name}_{platform}".format( - name = name, - platform = platform, - ), - sha256 = sha256, - patches = patches, - patch_strip = patch_strip, - platform = platform, - python_version = python_version, - release_filename = release_filename, - urls = urls, - strip_prefix = strip_prefix, - coverage_tool = coverage_tool, - **kwargs - ) - if register_toolchains: - native.register_toolchains("@{toolchain_repo_name}//:{platform}_toolchain".format( - toolchain_repo_name = toolchain_repo_name, - platform = platform, - )) - native.register_toolchains("@{toolchain_repo_name}//:{platform}_py_cc_toolchain".format( - toolchain_repo_name = toolchain_repo_name, - platform = platform, - )) - native.register_toolchains("@{toolchain_repo_name}//:{platform}_py_exec_tools_toolchain".format( - toolchain_repo_name = toolchain_repo_name, - platform = platform, - )) - - host_toolchain(name = name + "_host") - - toolchain_aliases( - name = name, - python_version = python_version, - user_repository_name = name, - platforms = loaded_platforms, - ) - - # in bzlmod we write out our own toolchain repos - if BZLMOD_ENABLED: - return - - toolchains_repo( - name = toolchain_repo_name, - python_version = python_version, - set_python_version_constraint = set_python_version_constraint, - user_repository_name = name, - ) - -def python_register_multi_toolchains( - name, - python_versions, - default_version = None, - minor_mapping = None, - **kwargs): - """Convenience macro for registering multiple Python toolchains. - - Args: - name: {type}`str` base name for each name in {obj}`python_register_toolchains` call. - python_versions: {type}`list[str]` the Python versions. - default_version: {type}`str` the default Python version. If not set, - the first version in python_versions is used. - minor_mapping: {type}`dict[str, str]` mapping between `X.Y` to `X.Y.Z` - format. Defaults to the value in `//python:versions.bzl`. - **kwargs: passed to each {obj}`python_register_toolchains` call. - """ - if len(python_versions) == 0: - fail("python_versions must not be empty") - - minor_mapping = minor_mapping or MINOR_MAPPING - - if not default_version: - default_version = python_versions.pop(0) - for python_version in python_versions: - if python_version == default_version: - # We register the default version lastly so that it's not picked first when --platforms - # is set with a constraint during toolchain resolution. This is due to the fact that - # Bazel will match the unconstrained toolchain if we register it before the constrained - # ones. - continue - python_register_toolchains( - name = name + "_" + python_version.replace(".", "_"), - python_version = python_version, - set_python_version_constraint = True, - minor_mapping = minor_mapping, - **kwargs - ) - python_register_toolchains( - name = name + "_" + default_version.replace(".", "_"), - python_version = default_version, - set_python_version_constraint = False, - minor_mapping = minor_mapping, - **kwargs - ) - - multi_toolchain_aliases( - name = name, - python_versions = { - python_version: name + "_" + python_version.replace(".", "_") - for python_version in (python_versions + [default_version]) - }, - minor_mapping = minor_mapping, - ) diff --git a/python/repositories.bzl b/python/repositories.bzl index 88c00e28cb..768b5874d5 100644 --- a/python/repositories.bzl +++ b/python/repositories.bzl @@ -16,14 +16,14 @@ """ load( - "//python/private:python_repositories.bzl", + "//python/private:is_standalone_interpreter.bzl", _STANDALONE_INTERPRETER_FILENAME = "STANDALONE_INTERPRETER_FILENAME", _is_standalone_interpreter = "is_standalone_interpreter", - _py_repositories = "py_repositories", - _python_register_multi_toolchains = "python_register_multi_toolchains", - _python_register_toolchains = "python_register_toolchains", - _python_repository = "python_repository", ) +load("//python/private:py_repositories.bzl", _py_repositories = "py_repositories") +load("//python/private:python_register_multi_toolchains.bzl", _python_register_multi_toolchains = "python_register_multi_toolchains") +load("//python/private:python_register_toolchains.bzl", _python_register_toolchains = "python_register_toolchains") +load("//python/private:python_repository.bzl", _python_repository = "python_repository") py_repositories = _py_repositories python_register_multi_toolchains = _python_register_multi_toolchains