diff --git a/python/extensions/pip.bzl b/python/extensions/pip.bzl index 2534deaca5..add69a4c64 100644 --- a/python/extensions/pip.bzl +++ b/python/extensions/pip.bzl @@ -27,6 +27,7 @@ load( ) load("@rules_python//python/pip_install:requirements_parser.bzl", parse_requirements = "parse") load("//python/private:normalize_name.bzl", "normalize_name") +load("//python/private:version_label.bzl", "version_label") def _whl_mods_impl(mctx): """Implementation of the pip.whl_mods tag class. @@ -84,7 +85,7 @@ def _create_versioned_pip_and_whl_repos(module_ctx, pip_attr, whl_map): # we programtically find it. hub_name = pip_attr.hub_name if python_interpreter_target == None: - python_name = "python_{}".format(pip_attr.python_version.replace(".", "_")) + python_name = "python_" + version_label(pip_attr.python_version, sep = "_") if python_name not in INTERPRETER_LABELS.keys(): fail(( "Unable to find interpreter for pip hub '{hub_name}' for " + @@ -96,7 +97,10 @@ def _create_versioned_pip_and_whl_repos(module_ctx, pip_attr, whl_map): )) python_interpreter_target = INTERPRETER_LABELS[python_name] - pip_name = hub_name + "_{}".format(pip_attr.python_version.replace(".", "")) + pip_name = "{}_{}".format( + hub_name, + version_label(pip_attr.python_version), + ) requrements_lock = locked_requirements_label(module_ctx, pip_attr) # Parse the requirements file directly in starlark to get the information diff --git a/python/private/coverage_deps.bzl b/python/private/coverage_deps.bzl index 8d1e5f4e86..93938e9a9e 100644 --- a/python/private/coverage_deps.bzl +++ b/python/private/coverage_deps.bzl @@ -17,6 +17,7 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe") +load("//python/private:version_label.bzl", "version_label") # Update with './tools/update_coverage_deps.py ' #START: managed by update_coverage_deps.py script @@ -116,8 +117,7 @@ def coverage_dep(name, python_version, platform, visibility): # for now as it is not actionable. return None - python_short_version = python_version.rpartition(".")[0] - abi = python_short_version.replace("3.", "cp3") + abi = "cp" + version_label(python_version) url, sha256 = _coverage_deps.get(abi, {}).get(platform, (None, "")) if url == None: diff --git a/python/private/version_label.bzl b/python/private/version_label.bzl new file mode 100644 index 0000000000..1bca92cfd8 --- /dev/null +++ b/python/private/version_label.bzl @@ -0,0 +1,36 @@ +# Copyright 2023 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. + +"" + +def version_label(version, *, sep = ""): + """A version fragment derived from python minor version + + Examples: + version_label("3.9") == "39" + version_label("3.9.12", sep="_") == "3_9" + version_label("3.11") == "311" + + Args: + version: Python version. + sep: The separator between major and minor version numbers, defaults + to an empty string. + + Returns: + The fragment of the version. + """ + major, _, version = version.partition(".") + minor, _, _ = version.partition(".") + + return major + sep + minor diff --git a/tests/version_label/BUILD.bazel b/tests/version_label/BUILD.bazel new file mode 100644 index 0000000000..1dcfece6cb --- /dev/null +++ b/tests/version_label/BUILD.bazel @@ -0,0 +1,17 @@ +# Copyright 2023 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. + +load(":version_label_test.bzl", "version_label_test_suite") + +version_label_test_suite(name = "version_label_tests") diff --git a/tests/version_label/version_label_test.bzl b/tests/version_label/version_label_test.bzl new file mode 100644 index 0000000000..b4ed6f9270 --- /dev/null +++ b/tests/version_label/version_label_test.bzl @@ -0,0 +1,52 @@ +# Copyright 2023 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. + +"" + +load("@rules_testing//lib:test_suite.bzl", "test_suite") +load("//python/private:version_label.bzl", "version_label") # buildifier: disable=bzl-visibility + +_tests = [] + +def _test_version_label_from_major_minor_version(env): + actual = version_label("3.9") + env.expect.that_str(actual).equals("39") + +_tests.append(_test_version_label_from_major_minor_version) + +def _test_version_label_from_major_minor_patch_version(env): + actual = version_label("3.9.3") + env.expect.that_str(actual).equals("39") + +_tests.append(_test_version_label_from_major_minor_patch_version) + +def _test_version_label_from_major_minor_version_custom_sep(env): + actual = version_label("3.9", sep = "_") + env.expect.that_str(actual).equals("3_9") + +_tests.append(_test_version_label_from_major_minor_version_custom_sep) + +def _test_version_label_from_complex_version(env): + actual = version_label("3.9.3-rc.0") + env.expect.that_str(actual).equals("39") + +_tests.append(_test_version_label_from_complex_version) + +def version_label_test_suite(name): + """Create the test suite. + + Args: + name: the name of the test suite + """ + test_suite(name = name, basic_tests = _tests)