diff --git a/gazelle/python/BUILD.bazel b/gazelle/python/BUILD.bazel index b988e493c7..ee2dce797b 100644 --- a/gazelle/python/BUILD.bazel +++ b/gazelle/python/BUILD.bazel @@ -54,7 +54,6 @@ copy_file( "@rules_python//python/config_settings:is_python_3.10": "@python_stdlib_list//:stdlib_list/lists/3.10.txt", "@rules_python//python/config_settings:is_python_3.11": "@python_stdlib_list//:stdlib_list/lists/3.11.txt", "@rules_python//python/config_settings:is_python_3.12": "@python_stdlib_list//:stdlib_list/lists/3.12.txt", - "@rules_python//python/config_settings:is_python_3.8": "@python_stdlib_list//:stdlib_list/lists/3.8.txt", "@rules_python//python/config_settings:is_python_3.9": "@python_stdlib_list//:stdlib_list/lists/3.9.txt", # This is the same behaviour as previously "//conditions:default": "@python_stdlib_list//:stdlib_list/lists/3.11.txt", diff --git a/python/private/config_settings.bzl b/python/private/config_settings.bzl index 3089b9c6cf..8bb932f94a 100644 --- a/python/private/config_settings.bzl +++ b/python/private/config_settings.bzl @@ -35,7 +35,13 @@ If the value is missing, then the default value is being used, see documentation # access it, but it's not intended for general public usage. _NOT_ACTUALLY_PUBLIC = ["//visibility:public"] -def construct_config_settings(*, name, default_version, versions, minor_mapping, documented_flags): # buildifier: disable=function-docstring +def construct_config_settings( + *, + name, + default_version, + versions, + minor_mapping, + documented_flags): # 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 @@ -109,13 +115,29 @@ def construct_config_settings(*, name, default_version, versions, minor_mapping, # 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. + first_minor = None for minor in minor_mapping.keys(): + if first_minor == None: + first_minor = minor + native.config_setting( name = "is_python_{}".format(minor), flag_values = {_PYTHON_VERSION_MAJOR_MINOR_FLAG: minor}, visibility = ["//visibility:public"], ) + for minor in range(int(first_minor.partition(".")[-1]) + 1): + minor = "3.{}".format(minor) + if minor in minor_mapping: + break + + # TODO @aignas 2025-11-04: use env-marker-setting with the smallest minor_mapping version + native.alias( + name = "is_python_{}".format(minor), + actual = "@platforms//:incompatible", + visibility = ["//visibility:public"], + ) + _current_config( name = "current_config", build_setting_default = "", diff --git a/python/private/full_version.bzl b/python/private/full_version.bzl index 0292d6c77d..82ac12e11e 100644 --- a/python/private/full_version.bzl +++ b/python/private/full_version.bzl @@ -14,12 +14,13 @@ """A small helper to ensure that we are working with full versions.""" -def full_version(*, version, minor_mapping): +def full_version(*, version, minor_mapping, err = True): """Return a full version. Args: version: {type}`str` the version in `X.Y` or `X.Y.Z` format. minor_mapping: {type}`dict[str, str]` mapping between `X.Y` to `X.Y.Z` format. + err: {type}`bool` whether to fail on error or return `None` instead. Returns: a full version given the version string. If the string is already a @@ -31,6 +32,8 @@ def full_version(*, version, minor_mapping): parts = version.split(".") if len(parts) == 3: return version + elif not err: + return None elif len(parts) == 2: fail( "Unknown Python version '{}', available values are: {}".format( diff --git a/python/private/pypi/hub_builder.bzl b/python/private/pypi/hub_builder.bzl index 58d35f2681..4f09f8102a 100644 --- a/python/private/pypi/hub_builder.bzl +++ b/python/private/pypi/hub_builder.bzl @@ -114,9 +114,25 @@ def _pip_parse(self, module_ctx, pip_attr): version = python_version, )) - self._platforms[python_version] = _platforms( - python_version = python_version, + full_python_version = full_version( + version = python_version, minor_mapping = self._minor_mapping, + err = False, + ) + if not full_python_version: + self._logger.warn(lambda: ( + "Ignoring pip python version '{version}' for hub " + + "'{hub}' in module '{module}' because there is no registered " + + "toolchain for it." + ).format( + hub = self.name, + module = self.module_name, + version = python_version, + )) + return + + self._platforms[python_version] = _platforms( + python_version = full_python_version, config = self._config, ) _set_get_index_urls(self, pip_attr) @@ -280,13 +296,10 @@ def _detect_interpreter(self, pip_attr): path = pip_attr.python_interpreter, ) -def _platforms(*, python_version, minor_mapping, config): +def _platforms(*, python_version, config): platforms = {} python_version = version.parse( - full_version( - version = python_version, - minor_mapping = minor_mapping, - ), + python_version, strict = True, ) diff --git a/python/private/python.bzl b/python/private/python.bzl index a1fe80e0ce..25af132f97 100644 --- a/python/private/python.bzl +++ b/python/private/python.bzl @@ -268,7 +268,12 @@ def _python_impl(module_ctx): full_python_version = full_version( version = toolchain_info.python_version, minor_mapping = py.config.minor_mapping, + err = False, ) + if not full_python_version: + logger.warn(lambda: "The python version '{}' is unknown, please configure a toolchain to be downloaded".format(toolchain_info.python_version)) + continue + kwargs = { "python_version": full_python_version, "register_coverage_tool": toolchain_info.register_coverage_tool, diff --git a/python/versions.bzl b/python/versions.bzl index 7e1b36b207..842fb39658 100644 --- a/python/versions.bzl +++ b/python/versions.bzl @@ -54,17 +54,6 @@ DEFAULT_RELEASE_BASE_URL = "https://github.com/astral-sh/python-build-standalone # # buildifier: disable=unsorted-dict-items TOOL_VERSIONS = { - "3.8.20": { - "url": "20241002/cpython-{python_version}+20241002-{platform}-{build}.tar.gz", - "sha256": { - "aarch64-apple-darwin": "2ddfc04bdb3e240f30fb782fa1deec6323799d0e857e0b63fa299218658fd3d4", - "aarch64-unknown-linux-gnu": "9d8798f9e79e0fc0f36fcb95bfa28a1023407d51a8ea5944b4da711f1f75f1ed", - "x86_64-apple-darwin": "68d060cd373255d2ca5b8b3441363d5aa7cc45b0c11bbccf52b1717c2b5aa8bb", - "x86_64-pc-windows-msvc": "41b6709fec9c56419b7de1940d1f87fa62045aff81734480672dcb807eedc47e", - "x86_64-unknown-linux-gnu": "285e141c36f88b2e9357654c5f77d1f8fb29cc25132698fe35bb30d787f38e87", - }, - "strip_prefix": "python", - }, "3.9.25": { "url": "20251031/cpython-{python_version}+20251031-{platform}-{build}.tar.gz", "sha256": { @@ -872,7 +861,6 @@ TOOL_VERSIONS = { # buildifier: disable=unsorted-dict-items MINOR_MAPPING = { - "3.8": "3.8.20", "3.9": "3.9.25", "3.10": "3.10.19", "3.11": "3.11.14",