# 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.

"Python toolchain module extensions for use with bzlmod."

load("@bazel_features//:features.bzl", "bazel_features")
load("//python:versions.bzl", "DEFAULT_RELEASE_BASE_URLS", "PLATFORMS")
load(":auth.bzl", "AUTH_ATTRS")
load(":full_version.bzl", "full_version")
load(
    ":pbs_manifest.bzl",
    "ARCHIVE_FLAVORS",
    "manifest_entry_platform_keys",
    "manifest_entry_sort_key",
    "parse_runtime_manifest",
)
load(":platform_info.bzl", "platform_info")
load(":pyproject_utils.bzl", "read_pyproject", "version_from_requires_python")
load(":python_register_toolchains.bzl", "python_register_toolchains")
load(":pythons_hub.bzl", "hub_repo")
load(":repo_utils.bzl", "repo_utils")
load(":runtimes_manifest.bzl", "MANIFEST_TEXT")
load(
    ":toolchains_repo.bzl",
    "host_compatible_python_repo",
    "multi_toolchain_aliases",
    "sorted_host_platform_names",
    "sorted_host_platforms",
)
load(":version.bzl", "version")

def parse_modules(
        *,
        module_ctx,
        logger = None,
        _fail = fail,
        _default_runtime_manifest = MANIFEST_TEXT):
    """Parse the modules and return a struct for registrations.

    Args:
        module_ctx: {type}`module_ctx` module context.
        logger: {type}`repo_utils.logger` A logger to use.
        _fail: {type}`function` the failure function, mainly for testing.
        _default_runtime_manifest: {type}`str` the built-in runtimes manifest,
            only overridden for testing.

    Returns:
        A struct with the following attributes:
        * `toolchains`: {type}`list[ToolchainConfig]` The list of toolchains to
          register. The last element is special and is treated as the default
          toolchain.
        * `config`: Various toolchain config, see `_get_toolchain_config`.
        * `debug_info`: {type}`None | dict` extra information to be passed
          to the debug repo.
        * `platforms`: {type}`dict[str, platform_info]` of the base set of
          platforms toolchains should be created for, if possible.

        ToolchainConfig struct:
            * python_version: str, full python version string
            * name: str, the base toolchain name, e.g., "python_3_10", no
              platform suffix.
            * register_coverage_tool: bool
    """
    if module_ctx.getenv("RULES_PYTHON_BZLMOD_DEBUG", "0") == "1":
        debug_info = {
            "toolchains_registered": [],
        }
    else:
        debug_info = None

    # The toolchain_info structs to register, in the order to register them in.
    # NOTE: The last element is special: it is treated as the default toolchain,
    # so there is special handling to ensure the last entry is the correct one.
    toolchains = []

    # We store the default toolchain separately to ensure it is the last
    # toolchain added to toolchains.
    # This is a toolchain_info struct.
    default_toolchain = None

    # Map of string Major.Minor or Major.Minor.Patch to the toolchain_info struct
    global_toolchain_versions = {}

    config = _get_toolchain_config(
        mctx = module_ctx,
        modules = module_ctx.modules,
        default_runtime_manifest = _default_runtime_manifest,
        _fail = _fail,
    )

    default_python_version = _compute_default_python_version(module_ctx)

    seen_versions = {}
    for mod in module_ctx.modules:
        module_toolchain_versions = []
        toolchain_attr_structs = _create_toolchain_attr_structs(
            mod = mod,
            seen_versions = seen_versions,
            config = config,
            default_python_version = default_python_version,
        )

        for toolchain_attr in toolchain_attr_structs:
            toolchain_version = toolchain_attr.python_version
            toolchain_name = "python_" + toolchain_version.replace(".", "_")

            # Duplicate versions within a module indicate a misconfigured module.
            if toolchain_version in module_toolchain_versions:
                _fail_duplicate_module_toolchain_version(toolchain_version, mod.name)
            module_toolchain_versions.append(toolchain_version)

            if mod.is_root:
                # Only the root module and rules_python are allowed to specify the default
                # toolchain for a couple reasons:
                # * It prevents submodules from specifying different defaults and only
                #   one of them winning.
                # * rules_python needs to set a soft default in case the root module doesn't,
                #   e.g. if the root module doesn't use Python itself.
                # * The root module is allowed to override the rules_python default.
                is_default = default_python_version == toolchain_version

            elif mod.name == "rules_python" and not default_toolchain:
                # This branch handles when the root module doesn't declare a
                # Python toolchain
                is_default = default_python_version == toolchain_version
            else:
                is_default = False

            if is_default and default_toolchain != None:
                _fail_multiple_default_toolchains_chosen(
                    first = default_toolchain.name,
                    second = toolchain_name,
                )

            # Ignore version collisions in the global scope because there isn't
            # much else that can be done. Modules don't know and can't control
            # what other modules do, so the first in the dependency graph wins.
            if toolchain_version in global_toolchain_versions:
                # If the python version is explicitly provided by the root
                # module, they should not be warned for choosing the same
                # version that rules_python provides as default.
                first = global_toolchain_versions[toolchain_version]
                if mod.name != "rules_python" or not first.module.is_root:
                    # The warning can be enabled by setting the verbosity:
                    # env RULES_PYTHON_REPO_DEBUG_VERBOSITY=INFO bazel build //...
                    _warn_duplicate_global_toolchain_version(
                        toolchain_version,
                        first = first,
                        second_toolchain_name = toolchain_name,
                        second_module_name = mod.name,
                        logger = logger or repo_utils.logger(module_ctx, "python", mod = mod),
                    )
                toolchain_info = None
            else:
                toolchain_info = struct(
                    python_version = toolchain_attr.python_version,
                    name = toolchain_name,
                    register_coverage_tool = toolchain_attr.configure_coverage_tool,
                    module = struct(name = mod.name, is_root = mod.is_root),
                )
                global_toolchain_versions[toolchain_version] = toolchain_info
                if debug_info:
                    debug_info["toolchains_registered"].append({
                        "module": {"is_root": mod.is_root, "name": mod.name},
                        "name": toolchain_name,
                    })

            if is_default:
                # This toolchain is setting the default, but the actual
                # registration was performed previously, by a different module.
                if toolchain_info == None:
                    default_toolchain = global_toolchain_versions[toolchain_version]

                    # Remove it because later code will add it at the end to
                    # ensure it is last in the list.
                    toolchains.remove(default_toolchain)
                else:
                    default_toolchain = toolchain_info
            elif toolchain_info:
                toolchains.append(toolchain_info)

    # A default toolchain is required so that the non-version-specific rules
    # are able to match a toolchain.
    if default_toolchain == None:
        fail("No default Python toolchain configured. Is rules_python missing `python.defaults()`?")
    elif default_toolchain.python_version not in global_toolchain_versions:
        fail('Default version "{python_version}" selected by module ' +
             '"{module_name}", but no toolchain with that version registered'.format(
                 python_version = default_toolchain.python_version,
                 module_name = default_toolchain.module.name,
             ))

    # The last toolchain in the BUILD file is set as the default
    # toolchain. We need the default last.
    toolchains.append(default_toolchain)

    # sort the toolchains so that the toolchain versions that are in the
    # `minor_mapping` are coming first. This ensures that `python_version =
    # "3.X"` transitions work as expected.
    minor_version_toolchains = []
    other_toolchains = []
    minor_mapping = list(config.minor_mapping.values())
    for t in toolchains:
        # FIXME @aignas 2025-04-04: How can we unit test that this ordering is
        # consistent with what would actually work?
        if config.minor_mapping.get(t.python_version, t.python_version) in minor_mapping:
            minor_version_toolchains.append(t)
        else:
            other_toolchains.append(t)
    toolchains = minor_version_toolchains + other_toolchains

    return struct(
        config = config,
        debug_info = debug_info,
        default_python_version = default_toolchain.python_version,
        toolchains = [
            struct(
                python_version = t.python_version,
                name = t.name,
                register_coverage_tool = t.register_coverage_tool,
            )
            for t in toolchains
        ],
    )

def _python_impl(module_ctx):
    py = parse_modules(module_ctx = module_ctx)

    # For all other processing (after parsing the modules) let's use a single logger.
    logger = repo_utils.logger(module_ctx, "python", mod = module_ctx.modules[0])

    # Host compatible runtime repos
    # dict[str version, struct] where struct has:
    # * full_python_version: str
    # * platform: platform_info struct
    # * platform_name: str platform name
    # * impl_repo_name: str repo name of the runtime's python_repository() repo
    all_host_compatible_impls = {}

    # Host compatible repos that still need to be created because, when
    # creating the actual runtime repo, there wasn't a host-compatible
    # variant defined for it.
    # dict[str reponame, struct] where struct has:
    # * compatible_version: str, e.g. 3.10 or 3.10.1. The version the host
    #   repo should be compatible with
    # * full_python_version: str, e.g. 3.10.1, the full python version of
    #   the toolchain that still needs a host repo created.
    needed_host_repos = {}

    # list of structs; see inline struct call within the loop below.
    toolchain_impls = []

    # list[str] of the repo names for host compatible repos
    all_host_compatible_repo_names = []

    # Create the underlying python_repository repos that contain the
    # python runtimes and their toolchain implementation definitions.
    for i, toolchain_info in enumerate(py.toolchains):
        is_last = (i + 1) == len(py.toolchains)

        # Ensure that we pass the full version here.
        full_python_version = full_version(
            version = toolchain_info.python_version,
            minor_mapping = py.config.minor_mapping,
            fail_on_err = False,
        )
        if (not full_python_version or
            full_python_version not in py.config.default["tool_versions"]):
            logger.info(lambda: (
                "The actual toolchain for python_version '{version}' " +
                "has not been registered, but was requested, please configure a toolchain " +
                "to be actually downloaded and setup"
            ).format(
                version = toolchain_info.python_version,
            ))
            continue

        kwargs = {
            "python_version": full_python_version,
            "register_coverage_tool": toolchain_info.register_coverage_tool,
        }

        # Allow overrides per python version
        kwargs.update(py.config.kwargs.get(toolchain_info.python_version, {}))
        kwargs.update(py.config.kwargs.get(full_python_version, {}))
        kwargs.update(py.config.default)
        register_result = python_register_toolchains(
            name = toolchain_info.name,
            _internal_bzlmod_toolchain_call = True,
            **kwargs
        )
        if not register_result.impl_repos:
            continue

        host_platforms = {}
        for repo_name, (platform_name, platform_info) in register_result.impl_repos.items():
            toolchain_impls.append(struct(
                # str: The base name to use for the toolchain() target
                name = repo_name,
                # str: The repo name the toolchain() target points to.
                impl_repo_name = repo_name,
                # str: platform key in the passed-in platforms dict
                platform_name = platform_name,
                # struct: platform_info() struct
                platform = platform_info,
                # str: Major.Minor.Micro python version
                full_python_version = full_python_version,
                # bool: whether to implicitly add the python version constraint
                # to the toolchain's target_settings.
                # The last toolchain is the default; it can't have version constraints
                set_python_version_constraint = is_last,
            ))
            if _is_compatible_with_host(module_ctx, platform_info):
                host_compat_entry = struct(
                    full_python_version = full_python_version,
                    platform = platform_info,
                    platform_name = platform_name,
                    impl_repo_name = repo_name,
                )
                host_platforms[platform_name] = host_compat_entry
                all_host_compatible_impls.setdefault(full_python_version, []).append(
                    host_compat_entry,
                )
                parsed_version = version.parse(full_python_version)
                all_host_compatible_impls.setdefault(
                    "{}.{}".format(*parsed_version.release[0:2]),
                    [],
                ).append(host_compat_entry)

        host_repo_name = toolchain_info.name + "_host"
        if host_platforms:
            all_host_compatible_repo_names.append(host_repo_name)
            host_platforms = sorted_host_platforms(host_platforms)
            entries = host_platforms.values()
            host_compatible_python_repo(
                name = host_repo_name,
                base_name = host_repo_name,
                # NOTE: Order matters. The first found to be compatible is
                # (usually) used.
                platforms = host_platforms.keys(),
                os_names = {str(i): e.platform.os_name for i, e in enumerate(entries)},
                arch_names = {str(i): e.platform.arch for i, e in enumerate(entries)},
                python_versions = {str(i): e.full_python_version for i, e in enumerate(entries)},
                impl_repo_names = {str(i): e.impl_repo_name for i, e in enumerate(entries)},
            )
        else:
            needed_host_repos[host_repo_name] = struct(
                compatible_version = toolchain_info.python_version,
                full_python_version = full_python_version,
            )

    if needed_host_repos:
        for key, entries in all_host_compatible_impls.items():
            all_host_compatible_impls[key] = sorted(
                entries,
                reverse = True,
                key = lambda e: version.key(version.parse(e.full_python_version)),
            )

    for host_repo_name, info in needed_host_repos.items():
        choices = []
        if info.compatible_version not in all_host_compatible_impls:
            logger.warn("No host compatible runtime found compatible with version {}".format(info.compatible_version))
            continue

        choices = all_host_compatible_impls[info.compatible_version]
        platform_keys = [
            # We have to prepend the offset because the same platform
            # name might occur across different versions
            "{}_{}".format(i, entry.platform_name)
            for i, entry in enumerate(choices)
        ]
        platform_keys = sorted_host_platform_names(platform_keys)

        all_host_compatible_repo_names.append(host_repo_name)
        host_compatible_python_repo(
            name = host_repo_name,
            base_name = host_repo_name,
            platforms = platform_keys,
            impl_repo_names = {
                str(i): entry.impl_repo_name
                for i, entry in enumerate(choices)
            },
            os_names = {str(i): entry.platform.os_name for i, entry in enumerate(choices)},
            arch_names = {str(i): entry.platform.arch for i, entry in enumerate(choices)},
            python_versions = {str(i): entry.full_python_version for i, entry in enumerate(choices)},
        )

    # list[str] The infix to use for the resulting toolchain() `name` arg.
    toolchain_names = []

    # dict[str i, str repo]; where repo is the full repo name
    # ("python_3_10_unknown-linux-x86_64") for the toolchain
    # i corresponds to index `i` in toolchain_names
    toolchain_repo_names = {}

    # dict[str i, list[str] constraints]; where constraints is a list
    # of labels for target_compatible_with
    # i corresponds to index `i` in toolchain_names
    toolchain_tcw_map = {}

    # dict[str i, list[str] settings]; where settings is a list
    # of labels for target_settings
    # i corresponds to index `i` in toolchain_names
    toolchain_ts_map = {}

    # dict[str i, str set_constraint]; where set_constraint is the string
    # "True" or "False".
    # i corresponds to index `i` in toolchain_names
    toolchain_set_python_version_constraints = {}

    # dict[str i, str python_version]; where python_version is the full
    # python version ("3.4.5").
    toolchain_python_versions = {}

    # dict[str i, str platform_key]; where platform_key is the key within
    # the PLATFORMS global for this toolchain
    toolchain_platform_keys = {}

    # Extra target_settings to add to every registered toolchain, e.g. for
    # gating the default toolchains behind a custom config_setting.
    global_add_target_settings = py.config.add_target_settings

    # Split the toolchain info into separate objects so they can be passed onto
    # the repository rule.
    for entry in toolchain_impls:
        key = str(len(toolchain_names))

        toolchain_names.append(entry.name)
        toolchain_repo_names[key] = entry.impl_repo_name
        toolchain_tcw_map[key] = entry.platform.compatible_with

        # The target_settings attribute may not be present for users
        # patching python/versions.bzl.
        toolchain_ts_map[key] = getattr(entry.platform, "target_settings", []) + global_add_target_settings
        toolchain_platform_keys[key] = entry.platform_name
        toolchain_python_versions[key] = entry.full_python_version

        # Repo rules can't accept dict[str, bool], so encode them as a string value.
        toolchain_set_python_version_constraints[key] = (
            "True" if entry.set_python_version_constraint else "False"
        )

    hub_repo(
        name = "pythons_hub",
        toolchain_names = toolchain_names,
        toolchain_repo_names = toolchain_repo_names,
        toolchain_target_compatible_with_map = toolchain_tcw_map,
        toolchain_target_settings_map = toolchain_ts_map,
        toolchain_platform_keys = toolchain_platform_keys,
        toolchain_python_versions = toolchain_python_versions,
        toolchain_set_python_version_constraints = toolchain_set_python_version_constraints,
        host_compatible_repo_names = sorted(all_host_compatible_repo_names),
        default_python_version = py.default_python_version,
        minor_mapping = py.config.minor_mapping,
        python_versions = list(py.config.default["tool_versions"].keys()),
    )

    # This is require in order to support multiple version py_test
    # and py_binary
    multi_toolchain_aliases(
        name = "python_versions",
        python_versions = {
            toolchain.python_version: toolchain.name
            for toolchain in py.toolchains
        },
    )

    if py.debug_info != None:
        _debug_repo(
            name = "rules_python_bzlmod_debug",
            debug_info = json.encode_indent(py.debug_info),
        )

    if bazel_features.external_deps.extension_metadata_has_reproducible:
        return module_ctx.extension_metadata(reproducible = True)
    else:
        return None

def _is_compatible_with_host(mctx, platform_info):
    os_name = repo_utils.get_platforms_os_name(mctx)
    cpu_name = repo_utils.get_platforms_cpu_name(mctx)
    return platform_info.os_name == os_name and platform_info.arch == cpu_name

def _one_or_the_same(first, second, *, onerror = None):
    if not first:
        return second
    if not second or second == first:
        return first
    if onerror:
        return onerror(first, second)
    else:
        fail("Unique value needed, got both '{}' and '{}', which are different".format(
            first,
            second,
        ))

def _fail_duplicate_module_toolchain_version(version, module):
    fail(("Duplicate module toolchain version: module '{module}' attempted " +
          "to use version '{version}' multiple times in itself").format(
        version = version,
        module = module,
    ))

def _warn_duplicate_global_toolchain_version(version, first, second_toolchain_name, second_module_name, logger):
    if not logger:
        return

    logger.info(lambda: (
        "Ignoring toolchain '{second_toolchain}' from module '{second_module}': " +
        "Toolchain '{first_toolchain}' from module '{first_module}' " +
        "already registered Python version {version} and has precedence."
    ).format(
        first_toolchain = first.name,
        first_module = first.module.name,
        second_module = second_module_name,
        second_toolchain = second_toolchain_name,
        version = version,
    ))

def _fail_multiple_defaults_python_version(first, second):
    fail(("Multiple python_version entries in defaults: " +
          "First default was python_version '{first}'. " +
          "Second was python_version '{second}'").format(
        first = first,
        second = second,
    ))

def _fail_multiple_defaults_python_version_file(first, second):
    fail(("Multiple python_version_file entries in defaults: " +
          "First default was python_version_file '{first}'. " +
          "Second was python_version_file '{second}'").format(
        first = first,
        second = second,
    ))

def _fail_multiple_defaults_python_version_env(first, second):
    fail(("Multiple python_version_env entries in defaults: " +
          "First default was python_version_env '{first}'. " +
          "Second was python_version_env '{second}'").format(
        first = first,
        second = second,
    ))

def _fail_multiple_default_toolchains_chosen(first, second):
    fail(("Multiple default toolchains: only one toolchain " +
          "can be chosen as a default. First default " +
          "was toolchain '{first}'. Second was '{second}'").format(
        first = first,
        second = second,
    ))

def _fail_multiple_default_toolchains_in_module(mod, toolchain_attrs):
    fail(("Multiple default toolchains: only one toolchain " +
          "can have is_default=True.\n" +
          "Module '{module}' contains {count} toolchains with " +
          "is_default=True: {versions}").format(
        module = mod.name,
        count = len(toolchain_attrs),
        versions = ", ".join(sorted([v.python_version for v in toolchain_attrs])),
    ))

def _validate_version(version_str, *, _fail = fail):
    v = version.parse(version_str, strict = True, _fail = _fail)
    if v == None:
        # Only reachable in tests
        return False

    if len(v.release) < 3:
        _fail("The 'python_version' attribute needs to specify the full version in at least 'X.Y.Z' format, got: '{}'".format(v.string))
        return False

    return True

def _process_single_version_overrides(*, tag, _fail = fail, default):
    if not _validate_version(tag.python_version, _fail = _fail):
        return

    available_versions = default["tool_versions"]
    kwargs = default.setdefault("kwargs", {})

    if tag.python_version not in available_versions:
        if not (tag.sha256 and tag.urls):
            _fail((
                "When introducing a new python_version '{}', 'sha256' and " +
                "'urls' must be specified"
            ).format(tag.python_version))
            return

    if tag.sha256 or tag.urls:
        if not (tag.sha256 and tag.urls):
            _fail("Both `sha256` and `urls` overrides need to be provided together")
            return

        for platform in (tag.sha256 or []):
            if platform not in default["platforms"]:
                _fail("The platform must be one of {allowed} but got '{got}'".format(
                    allowed = sorted(default["platforms"]),
                    got = platform,
                ))
                return

    sha256 = dict(tag.sha256) or available_versions[tag.python_version]["sha256"]
    if tag.urls:
        strip_prefix = {
            platform: tag.strip_prefix
            for platform in sha256
        }
    else:
        # The archives are not overridden, so keep their strip_prefix, which
        # differs between the archive flavors.
        strip_prefix = available_versions[tag.python_version]["strip_prefix"]
    override = {
        "sha256": sha256,
        "strip_prefix": strip_prefix,
        "url": {
            platform: list(tag.urls)
            for platform in tag.sha256
        } or available_versions[tag.python_version]["url"],
    }

    if tag.patches:
        override["patch_strip"] = {
            platform: tag.patch_strip
            for platform in sha256
        }
        override["patches"] = {
            platform: list(tag.patches)
            for platform in sha256
        }

    available_versions[tag.python_version] = {k: v for k, v in override.items() if v}

    if tag.distutils_content:
        kwargs.setdefault(tag.python_version, {})["distutils_content"] = tag.distutils_content
    if tag.distutils:
        kwargs.setdefault(tag.python_version, {})["distutils"] = tag.distutils
    if tag.libpython and tag.libpython != "auto":
        kwargs.setdefault(tag.python_version, {})["libpython"] = tag.libpython

def _process_single_version_platform_overrides(*, tag, _fail = fail, default):
    if not _validate_version(tag.python_version, _fail = _fail):
        return

    available_versions = default["tool_versions"]

    if tag.python_version not in available_versions:
        if not tag.urls or not tag.sha256 or not tag.strip_prefix:
            _fail("When introducing a new python_version '{}', 'sha256', 'strip_prefix' and 'urls' must be specified".format(tag.python_version))
            return
        available_versions[tag.python_version] = {}

    if tag.coverage_tool:
        # NOTE: tag.coverage_tool is a Label (so that it is resolved relative to the
        # calling module), but downstream (python_repository.coverage_tool) it is
        # consumed as a string, so convert it to its canonical string form here.
        available_versions[tag.python_version].setdefault("coverage_tool", {})[tag.platform] = str(tag.coverage_tool)
    if tag.patch_strip:
        available_versions[tag.python_version].setdefault("patch_strip", {})[tag.platform] = tag.patch_strip
    if tag.patches:
        available_versions[tag.python_version].setdefault("patches", {})[tag.platform] = list(tag.patches)
    if tag.sha256:
        available_versions[tag.python_version].setdefault("sha256", {})[tag.platform] = tag.sha256
    if tag.strip_prefix:
        available_versions[tag.python_version].setdefault("strip_prefix", {})[tag.platform] = tag.strip_prefix

    if tag.urls:
        available_versions[tag.python_version].setdefault("url", {})[tag.platform] = tag.urls
    if tag.libpython and tag.libpython != "auto":
        available_versions[tag.python_version].setdefault("libpython", {})[tag.platform] = tag.libpython

    # If platform is customized, or doesn't exist, (re)define one.
    if ((tag.target_compatible_with or tag.target_settings or tag.os_name or tag.arch) or
        tag.platform not in default["platforms"]):
        os_name = tag.os_name
        arch = tag.arch

        if not tag.target_compatible_with:
            target_compatible_with = []
            if os_name:
                target_compatible_with.append("@platforms//os:{}".format(
                    repo_utils.get_platforms_os_name(os_name),
                ))
            if arch:
                target_compatible_with.append("@platforms//cpu:{}".format(
                    repo_utils.get_platforms_cpu_name(arch),
                ))
        else:
            target_compatible_with = tag.target_compatible_with

        # For lack of a better option, give a bogus value. It only affects
        # if the runtime is considered host-compatible.
        if not os_name:
            os_name = "UNKNOWN_CUSTOM_OS"
        if not arch:
            arch = "UNKNOWN_CUSTOM_ARCH"

        # Move the override earlier in the ordering -- the platform key ordering
        # becomes the toolchain ordering within the version. This allows the
        # override to have a superset of constraints from a regular runtimes
        # (e.g. same platform, but with a custom flag required).
        override_first = {
            tag.platform: platform_info(
                compatible_with = target_compatible_with,
                target_settings = tag.target_settings,
                os_name = os_name,
                arch = arch,
            ),
        }
        for key, value in default["platforms"].items():
            # Don't replace our override with the old value
            if key in override_first:
                continue
            override_first[key] = value

        default["platforms"] = override_first

def _process_global_overrides(*, tag, default, _fail = fail):
    if tag.available_python_versions:
        available_versions = default["tool_versions"]
        all_versions = dict(available_versions)
        available_versions.clear()
        for v in tag.available_python_versions:
            if v not in all_versions:
                _fail("unknown version '{}', known versions are: {}".format(
                    v,
                    sorted(all_versions),
                ))
                return

            available_versions[v] = all_versions[v]

    if tag.minor_mapping:
        for minor_version, full_version in tag.minor_mapping.items():
            parsed = version.parse(minor_version, strict = True, _fail = _fail)
            if len(parsed.release) > 2 or parsed.pre or parsed.post or parsed.dev or parsed.local:
                fail("Expected the key to be of `X.Y` format but got `{}`".format(parsed.string))

            # Ensure that the version is valid
            version.parse(full_version, strict = True, _fail = _fail)

        default["minor_mapping"] = tag.minor_mapping

    if tag.add_target_settings:
        default["add_target_settings"] = list(tag.add_target_settings)

    forwarded_attrs = sorted(AUTH_ATTRS) + [
        "base_urls",
        "libpython",
        "register_all_versions",
    ]
    for key in forwarded_attrs:
        if getattr(tag, key, None):
            default[key] = getattr(tag, key)

def _override_defaults(*overrides, modules, _fail = fail, default):
    mod = modules[0] if modules else None
    if not mod or not mod.is_root:
        return

    overriden_keys = []

    for override in overrides:
        for tag in getattr(mod.tags, override.name):
            key = override.key(tag)
            if key not in overriden_keys:
                overriden_keys.append(key)
            elif key:
                _fail("Only a single 'python.{}' can be present for '{}'".format(override.name, key))
                return
            else:
                _fail("Only a single 'python.{}' can be present".format(override.name))
                return

            override.fn(tag = tag, _fail = _fail, default = default)

def _populate_from_pbs_manifest(
        *,
        mctx,
        add_runtime_manifest_urls = [],
        add_runtime_manifest_files = [],
        add_runtime_manifest_contents = [],
        runtime_manifest_sha = "",
        base_urls = [],
        available_versions,
        _fail):
    manifest_contents = list(add_runtime_manifest_contents)

    if add_runtime_manifest_urls:
        manifest_path = mctx.path("runtime_manifest")
        result = mctx.download(
            url = add_runtime_manifest_urls,
            output = manifest_path,
            sha256 = runtime_manifest_sha,
        )
        if not result.success:
            _fail("Failed to download manifest from {}: {}".format(add_runtime_manifest_urls, result))
            return
        manifest_contents.append(mctx.read(manifest_path))

    for manifest_file in add_runtime_manifest_files:
        manifest_contents.append(mctx.read(manifest_file, watch = "yes"))

    if not manifest_contents:
        return

    base_download_urls = [url.rpartition("/")[0] for url in add_runtime_manifest_urls]
    if not base_download_urls and base_urls:
        base_download_urls = list(base_urls)

    entries = []
    for content in manifest_contents:
        entries.extend(parse_runtime_manifest(content))

    entries = sorted(
        entries,
        key = manifest_entry_sort_key,
    )

    for entry in entries:
        location = entry.location
        sha256 = entry.sha256
        py_version = entry.python_version

        # Fallback to matching against PLATFORMS keys as before to ensure compatibility
        # with rules_python expected platform keys.
        matched_platform = "{}-{}-{}".format(entry.arch, entry.vendor, entry.os)
        if entry.libc:
            matched_platform += "-" + entry.libc
        if entry.freethreaded:
            matched_platform += "-freethreaded"

        if matched_platform not in PLATFORMS:
            continue

        if entry.archive_flavor not in ARCHIVE_FLAVORS:
            continue

        v_dict = available_versions.setdefault(py_version, {})
        if "://" in location:
            urls = [location]
        else:
            urls = []
            for b_url in base_download_urls:
                if ("/" not in location and
                    entry.build_version and
                    b_url in DEFAULT_RELEASE_BASE_URLS):
                    urls.append(
                        "{}/{}/{}".format(b_url, entry.build_version, location),
                    )
                else:
                    urls.append("{}/{}".format(b_url, location))

        strip_prefix = "python/install" if entry.archive_flavor == "full" else "python"

        # The plain platform key gets the preferred archive; the flavor
        # specific key (if any) gets the archive of that flavor.
        for platform_key in manifest_entry_platform_keys(entry, matched_platform):
            if platform_key in v_dict.get("sha256", {}):
                continue
            v_dict.setdefault("sha256", {})[platform_key] = sha256
            v_dict.setdefault("url", {})[platform_key] = urls
            v_dict.setdefault("strip_prefix", {})[platform_key] = strip_prefix

def _get_toolchain_config(
        *,
        mctx,
        modules,
        default_runtime_manifest,
        _fail = fail):
    """Computes the configs for toolchains.

    Args:
        mctx: The module context.
        modules: The modules from module_ctx
        default_runtime_manifest: The contents of the built-in runtimes
            manifest.
        _fail: Function to call for failing; only used for testing.

    Returns:
        A struct with the following:
        * `kwargs`: {type}`dict[str, dict[str, object]` custom kwargs to pass to
          `python_register_toolchains`, keyed by python version.
          The first key is either a Major.Minor or Major.Minor.Patch
          string.
        * `minor_mapping`: {type}`dict[str, str]` the mapping of Major.Minor
          to Major.Minor.Patch.
        * `default`: {type}`dict[str, object]` of kwargs passed along to
          `python_register_toolchains`. These keys take final precedence.
        * `register_all_versions`: {type}`bool` whether all known versions
          should be registered.
    """

    # Items that can be overridden
    available_versions = {}
    root_module = modules[0] if modules else None
    root_overrides = root_module.tags.override if root_module and root_module.is_root else []

    _populate_from_pbs_manifest(
        mctx = mctx,
        # Loaded rather than read by Label, so the remote repo contents cache
        # does not have to materialize this repo.
        add_runtime_manifest_contents = [default_runtime_manifest],
        base_urls = DEFAULT_RELEASE_BASE_URLS,
        available_versions = available_versions,
        _fail = _fail,
    )

    for tag in root_overrides:
        if tag.add_runtime_manifest_urls or tag.add_runtime_manifest_files:
            _populate_from_pbs_manifest(
                mctx = mctx,
                add_runtime_manifest_urls = tag.add_runtime_manifest_urls,
                add_runtime_manifest_files = tag.add_runtime_manifest_files,
                runtime_manifest_sha = tag.runtime_manifest_sha,
                base_urls = tag.base_urls,
                available_versions = available_versions,
                _fail = _fail,
            )

    default = {
        "base_urls": DEFAULT_RELEASE_BASE_URLS,
        "platforms": dict(PLATFORMS),  # Copy so it's mutable.
        "tool_versions": available_versions,
    }

    _override_defaults(
        # First override by single version, because the sha256 will replace
        # anything that has been there before.
        struct(
            name = "single_version_override",
            key = lambda t: t.python_version,
            fn = _process_single_version_overrides,
        ),
        # Then override particular platform entries if they need to be overridden.
        struct(
            name = "single_version_platform_override",
            key = lambda t: (t.python_version, t.platform),
            fn = _process_single_version_platform_overrides,
        ),
        # Then finally add global args and remove the unnecessary toolchains.
        # This ensures that we can do further validations when removing.
        struct(
            name = "override",
            key = lambda t: None,
            fn = _process_global_overrides,
        ),
        modules = modules,
        default = default,
        _fail = _fail,
    )

    register_all_versions = default.pop("register_all_versions", False)
    add_target_settings = default.pop("add_target_settings", [])
    kwargs = default.pop("kwargs", {})

    versions = {}
    for version_string in available_versions:
        v = version.parse(version_string, strict = True)
        versions.setdefault(
            "{}.{}".format(v.release[0], v.release[1]),
            [],
        ).append((version.key(v), v.string))

    minor_mapping = {
        major_minor: max(subset)[1]
        for major_minor, subset in versions.items()
    }

    # The following ensures that all of the versions will be present in the minor_mapping
    minor_mapping_overrides = default.pop("minor_mapping", {})
    for major_minor, full in minor_mapping_overrides.items():
        minor_mapping[major_minor] = full

    return struct(
        kwargs = kwargs,
        minor_mapping = minor_mapping,
        default = default,
        register_all_versions = register_all_versions,
        add_target_settings = add_target_settings,
    )

def _compute_default_python_version(mctx):
    default_python_version = None
    for mod in mctx.modules:
        # Only the root module and rules_python are allowed to specify the default
        # toolchain for a couple reasons:
        # * It prevents submodules from specifying different defaults and only
        #   one of them winning.
        # * rules_python needs to set a soft default in case the root module doesn't,
        #   e.g. if the root module doesn't use Python itself.
        # * The root module is allowed to override the rules_python default.
        if not (mod.is_root or mod.name == "rules_python"):
            continue

        defaults_attr_structs = _create_defaults_attr_structs(mod = mod)
        default_python_version_env = None
        default_python_version_file = None
        pyproject_toml_label = None

        for defaults_attr in defaults_attr_structs:
            pyproject_toml_label = _one_or_the_same(
                pyproject_toml_label,
                defaults_attr.pyproject_toml,
                onerror = lambda: fail("Multiple pyproject.toml files specified in defaults"),
            )

            default_python_version = _one_or_the_same(
                default_python_version,
                defaults_attr.python_version,
                onerror = _fail_multiple_defaults_python_version,
            )
            default_python_version_env = _one_or_the_same(
                default_python_version_env,
                defaults_attr.python_version_env,
                onerror = _fail_multiple_defaults_python_version_env,
            )
            default_python_version_file = _one_or_the_same(
                default_python_version_file,
                defaults_attr.python_version_file,
                onerror = _fail_multiple_defaults_python_version_file,
            )

        # Priority order: ENV > pyproject_toml >  python_version_file > python_version
        if default_python_version_file:
            default_python_version = _one_or_the_same(
                default_python_version,
                mctx.read(default_python_version_file, watch = "yes").strip(),
            )
        if pyproject_toml_label:
            pyproject = read_pyproject(mctx, pyproject_toml_label)
            if pyproject.requires_python:
                default_python_version = version_from_requires_python(pyproject.requires_python)
        if default_python_version_env:
            default_python_version = mctx.getenv(
                default_python_version_env,
                default_python_version,
            )

        if default_python_version:
            break

        # Otherwise, look at legacy python.toolchain() calls for a default
        toolchain_attrs = mod.tags.toolchain

        # Convenience: if one python.toolchain() call exists, treat it as
        # the default.
        if len(toolchain_attrs) == 1:
            default_python_version = toolchain_attrs[0].python_version
        else:
            sets_default = [v for v in toolchain_attrs if v.is_default]
            if len(sets_default) == 1:
                default_python_version = sets_default[0].python_version
            elif len(sets_default) > 1:
                _fail_multiple_default_toolchains_in_module(mod, toolchain_attrs)

        if default_python_version:
            break

    return default_python_version

def _create_defaults_attr_structs(*, mod):
    arg_structs = []

    for tag in mod.tags.defaults:
        arg_structs.append(_create_defaults_attr_struct(tag = tag))

    return arg_structs

def _create_defaults_attr_struct(*, tag):
    return struct(
        python_version = getattr(tag, "python_version", None),
        python_version_env = getattr(tag, "python_version_env", None),
        python_version_file = getattr(tag, "python_version_file", None),
        pyproject_toml = getattr(tag, "pyproject_toml", None),
    )

def _create_toolchain_attr_structs(*, mod, config, seen_versions, default_python_version):
    arg_structs = []

    # Auto-register a toolchain for the default version if not already
    # registered via an explicit python.toolchain() call.
    # This works for any default source: pyproject_toml, python_version_file,
    # python_version_env, or python_version.
    has_explicit_toolchain = default_python_version and any([
        tag.python_version == default_python_version
        for tag in mod.tags.toolchain
    ])
    if (default_python_version and
        default_python_version not in seen_versions and
        mod.is_root and not has_explicit_toolchain):
        arg_structs.append(_create_toolchain_attrs_struct(
            python_version = default_python_version,
            toolchain_tag_count = 1,
        ))
        seen_versions[default_python_version] = True

    for tag in mod.tags.toolchain:
        arg_structs.append(_create_toolchain_attrs_struct(
            tag = tag,
            toolchain_tag_count = len(mod.tags.toolchain),
        ))

        seen_versions[tag.python_version] = True

    if config.register_all_versions:
        arg_structs.extend([
            _create_toolchain_attrs_struct(python_version = v)
            for v in config.default["tool_versions"].keys() + config.minor_mapping.keys()
            if v not in seen_versions
        ])

    return arg_structs

def _create_toolchain_attrs_struct(
        *,
        tag = None,
        python_version = None,
        toolchain_tag_count = None):
    if tag and python_version:
        fail("Only one of tag and python version can be specified")
    if tag:
        # A single toolchain is treated as the default because it's unambiguous.
        is_default = tag.is_default or toolchain_tag_count == 1
    else:
        is_default = False

    return struct(
        is_default = is_default,
        python_version = python_version if python_version else tag.python_version,
        configure_coverage_tool = getattr(tag, "configure_coverage_tool", False),
    )

_defaults = tag_class(
    doc = """Tag class to specify the default Python version.""",
    attrs = {
        "pyproject_toml": attr.label(
            mandatory = False,
            doc = """\
Label pointing to pyproject.toml file to read the default Python version from.
When specified, reads the `requires-python` field from pyproject.toml.
The version must be specified as `==X.Y.Z` (exact version with full semver).

:::{versionadded} 2.3.0
:::
""",
        ),
        "python_version": attr.string(
            mandatory = False,
            doc = """\
String saying what the default Python version should be. If the string
matches the {attr}`python_version` attribute of a toolchain, this
toolchain is the default version. If this attribute is set, the
{attr}`is_default` attribute of the toolchain is ignored.

:::{versionadded} 1.4.0
:::
""",
        ),
        "python_version_env": attr.string(
            mandatory = False,
            doc = """\
Environment variable saying what the default Python version should be.
If the string matches the {attr}`python_version` attribute of a
toolchain, this toolchain is the default version. If this attribute is
set, the {attr}`is_default` attribute of the toolchain is ignored.

:::{versionadded} 1.4.0
:::
""",
        ),
        "python_version_file": attr.label(
            mandatory = False,
            allow_single_file = True,
            doc = """\
File saying what the default Python version should be. If the contents
of the file match the {attr}`python_version` attribute of a toolchain,
this toolchain is the default version. If this attribute is set, the
{attr}`is_default` attribute of the toolchain is ignored.

:::{versionadded} 1.4.0
:::
""",
        ),
    },
)

_toolchain = tag_class(
    doc = """Tag class used to register Python toolchains.
Use this tag class to register one or more Python toolchains. This class
is also potentially called by sub modules. The following covers different
business rules and use cases.

:::{topic} Toolchains in the Root Module

This class registers all toolchains in the root module.
:::

:::{topic} Toolchains in Sub Modules

It will create a toolchain that is in a sub module, if the toolchain
of the same name does not exist in the root module.  The extension stops name
clashing between toolchains in the root module and toolchains in sub modules.
You cannot configure more than one toolchain as the default toolchain.
:::

:::{topic} Toolchain set as the default version

This extension will not create a toolchain that exists in a sub module,
if the sub module toolchain is marked as the default version. If you have
more than one toolchain in your root module, you need to set one of the
toolchains as the default version.  If there is only one toolchain it
is set as the default toolchain.
:::

:::{topic} Toolchain repository name

A toolchain's repository name uses the format `python_{major}_{minor}`, e.g.
`python_3_10`. The `major` and `minor` components are
`major` and `minor` are the Python version from the `python_version` attribute.

If a toolchain is registered in `X.Y.Z`, then similarly the toolchain name will
be `python_{major}_{minor}_{patch}`, e.g. `python_3_10_19`.
:::

:::{topic} Toolchain detection
The definition of the first toolchain wins, which means that the root module
can override settings for any python toolchain available. This relies on the
documented module traversal from the {obj}`module_ctx.modules`.
:::

:::{tip}
In order to use a different name than the above, you can use the following `MODULE.bazel`
syntax:
```starlark
python = use_extension("@rules_python//python/extensions:python.bzl", "python")
python.defaults(python_version = "3.14")
python.toolchain(python_version = "3.14")

use_repo(python, my_python_name = "python_3_14")
```

Then the python interpreter will be available as `my_python_name`.
:::
""",
    attrs = {
        "configure_coverage_tool": attr.bool(
            mandatory = False,
            doc = "Whether or not to configure the default coverage tool provided by `rules_python` for the compatible toolchains.",
        ),
        "ignore_root_user_error": attr.bool(
            default = True,
            doc = """\
:::{versionchanged} 1.8.0
Noop, will be removed in the next major release.
:::
""",
            mandatory = False,
        ),
        "is_default": attr.bool(
            mandatory = False,
            doc = """\
Whether the toolchain is the default version.

:::{versionchanged} 1.4.0
This setting is ignored if the default version is set using the `defaults`
tag class (encouraged).
:::
""",
        ),
        "python_version": attr.string(
            mandatory = True,
            doc = """\
The Python version, in `major.minor` or `major.minor.patch` format, e.g
`3.12` (or `3.12.3`), to create a toolchain for.
""",
        ),
    },
)

_override = tag_class(
    doc = """Tag class used to override defaults and behaviour of the module extension.

:::{versionadded} 0.36.0
:::
""",
    attrs = {
        "add_runtime_manifest_files": attr.label_list(
            mandatory = False,
            allow_files = True,
            doc = """
Labels pointing to local python-build-standalone manifest files (e.g., `SHA256SUMS`).

Example:
`//my/custom/manifest:SHA256SUMS`

:::{seealso}
[Manifest file format documentation](https://rules-python.readthedocs.io/en/latest/toolchains.html#manifest-file-format)
:::

:::{versionadded} 2.1.0
:::
""",
        ),
        "add_runtime_manifest_urls": attr.string_list(
            mandatory = False,
            doc = """
URLs pointing to python-build-standalone manifest files (e.g., SHA256SUMS).

Example:
`https://github.com/astral-sh/python-build-standalone/releases/download/20260414/SHA256SUMS`

Note that `/latest/` can be used in place of a specific release date (e.g., `20260414`) to automatically use the latest release:
`https://github.com/astral-sh/python-build-standalone/releases/latest/download/SHA256SUMS`

:::{seealso}
[Manifest file format documentation](https://rules-python.readthedocs.io/en/latest/toolchains.html#manifest-file-format)
:::

:::{versionadded} 2.1.0
:::
""",
        ),
        "add_target_settings": attr.string_list(
            mandatory = False,
            doc = """\
A list of `config_setting` labels to add to the `target_settings` of every
toolchain registered by this module extension. This is useful for creating
separate "families" of toolchains gated behind custom build settings.

For example, to ensure the default prebuilt toolchains are only resolved when
a `prebuilt` config setting is active:

```starlark
python.override(
    add_target_settings = ["@@//:python_toolchain_family_prebuilt"],
)
```

These settings are appended to the `target_settings` of all toolchains
registered by the extension, including any that already have settings
from `python.single_version_platform_override`.

:::{versionadded} 2.1.0
:::
""",
        ),
        "available_python_versions": attr.string_list(
            mandatory = False,
            doc = """\
The list of available python tool versions to use. Must be in `X.Y.Z` format.
If the unknown version given the processing of the extension will fail - all of
the versions in the list have to be defined with
{obj}`python.single_version_override` or
{obj}`python.single_version_platform_override` before they are used in this
list.

This attribute is usually used in order to ensure that no unexpected transitive
dependencies are introduced.
""",
        ),
        "base_urls": attr.string_list(
            mandatory = False,
            doc = "The base URLs to be used when downloading toolchains.",
            default = DEFAULT_RELEASE_BASE_URLS,
        ),
        "ignore_root_user_error": attr.bool(
            default = True,
            doc = """Deprecated; do not use. This attribute has no effect.""",
            mandatory = False,
        ),
        "libpython": attr.string(
            default = "auto",
            doc = """Whether to include shared libpython files.

Valid values are `auto`, `include`, and `exclude`. With `auto`, recognized
Astral Python Standalone builds from 20250517 onward exclude the shared
libraries; other runtimes retain them.

:::{versionadded} 2.4.0
:::
""",
            values = ["auto", "include", "exclude"],
        ),
        "minor_mapping": attr.string_dict(
            mandatory = False,
            doc = """\
The mapping between `X.Y` to `X.Y.Z` versions to be used when setting up
toolchains. It defaults to the interpreter with the highest available patch
version for each minor version. For example if one registers `3.10.3`, `3.10.4`
and `3.11.4` then the default for the `minor_mapping` dict will be:
```starlark
{
"3.10": "3.10.4",
"3.11": "3.11.4",
}
```

:::{versionchanged} 0.37.0
The values in this mapping override the default values and do not replace them.
:::
""",
            default = {},
        ),
        "register_all_versions": attr.bool(default = False, doc = "Add all versions"),
        "runtime_manifest_sha": attr.string(
            mandatory = False,
            doc = """
SHA256 hash for the add_runtime_manifest_urls.

:::{versionadded} 2.1.0
:::
""",
        ),
    } | AUTH_ATTRS,
)

_single_version_override = tag_class(
    doc = """Override single python version URLs and patches for all platforms.

:::{note}
This will replace any existing configuration for the given python version.
:::

:::{tip}
If you would like to modify the configuration for a specific `(version,
platform)`, please use the {obj}`single_version_platform_override` tag
class.
:::

:::{versionadded} 0.36.0
:::
""",
    attrs = {
        # NOTE @aignas 2024-09-01: all of the attributes except for `version`
        # can be part of the `python.toolchain` call. That would make it more
        # ergonomic to define new toolchains and to override values for old
        # toolchains. The same semantics of the `first one wins` would apply,
        # so technically there is no need for any overrides?
        #
        # Although these attributes would override the code that is used by the
        # code in non-root modules, so technically this could be thought as
        # being overridden.
        #
        # rules_go has a single download call:
        # https://github.com/bazelbuild/rules_go/blob/master/go/private/extensions.bzl#L38
        #
        # However, we need to understand how to accommodate the fact that
        # {attr}`single_version_override.version` only allows patch versions.
        "distutils": attr.label(
            allow_single_file = True,
            doc = "A distutils.cfg file to be included in the Python installation. " +
                  "Either {attr}`distutils` or {attr}`distutils_content` can be specified, but not both.",
            mandatory = False,
        ),
        "distutils_content": attr.string(
            doc = "A distutils.cfg file content to be included in the Python installation. " +
                  "Either {attr}`distutils` or {attr}`distutils_content` can be specified, but not both.",
            mandatory = False,
        ),
        "libpython": attr.string(
            default = "auto",
            doc = """Whether to include shared libpython files.

Valid values are `auto`, `include`, and `exclude`. With `auto`, recognized
Astral Python Standalone builds from 20250517 onward exclude the shared
libraries; other runtimes retain them.

:::{versionadded} 2.4.0
:::
""",
            values = ["auto", "include", "exclude"],
        ),
        "patch_strip": attr.int(
            mandatory = False,
            doc = "Same as the --strip argument of Unix patch.",
            default = 0,
        ),
        "patches": attr.label_list(
            mandatory = False,
            doc = "A list of labels pointing to patch files to apply for the interpreter repository. They are applied in the list order and are applied before any platform-specific patches are applied.",
        ),
        "python_version": attr.string(
            mandatory = True,
            doc = "The python version to override URLs for. Must be in `X.Y.Z` format.",
        ),
        "sha256": attr.string_dict(
            mandatory = False,
            doc = "The python platform to sha256 dict. See {attr}`python.single_version_platform_override.platform` for allowed key values.",
        ),
        "strip_prefix": attr.string(
            mandatory = False,
            doc = "The 'strip_prefix' for the archive, defaults to 'python'.",
            default = "python",
        ),
        "urls": attr.string_list(
            mandatory = False,
            doc = "The URL template to fetch releases for this Python version. See {attr}`python.single_version_platform_override.urls` for documentation.",
        ),
    },
)

_single_version_platform_override = tag_class(
    doc = """Override single python version for a single existing platform.

If the `(version, platform)` is new, we will add it to the existing versions and will
use the same `url` template.

:::{tip}
If you would like to add or remove platforms to a single python version toolchain
configuration, please use {obj}`single_version_override`.
:::

:::{versionadded} 0.36.0
:::
""",
    attrs = {
        "arch": attr.string(
            doc = """
The arch (cpu) the runtime is compatible with.

If not set, then the runtime cannot be used as a `python_X_Y_host` runtime.

If set, the `os_name`, `target_compatible_with` and `target_settings` attributes
should also be set.

The values should be one of the values in `@platforms//cpu`

:::{seealso}
Docs for [Registering custom runtimes]
:::

:::{versionadded} 1.5.0
:::
""",
        ),
        "coverage_tool": attr.label(
            doc = """\
The coverage tool to be used for a particular Python interpreter. This can override
`rules_python` defaults.
""",
        ),
        "libpython": attr.string(
            default = "auto",
            doc = """Whether to include shared libpython files.

Valid values are `auto`, `include`, and `exclude`. With `auto`, recognized
Astral Python Standalone builds from 20250517 onward exclude the shared
libraries; other runtimes retain them.

:::{versionadded} 2.4.0
:::
""",
            values = ["auto", "include", "exclude"],
        ),
        "os_name": attr.string(
            doc = """
The host OS the runtime is compatible with.

If not set, then the runtime cannot be used as a `python_X_Y_host` runtime.

If set, the `os_name`, `target_compatible_with` and `target_settings` attributes
should also be set.

The values should be one of the values in `@platforms//os`

:::{seealso}
Docs for [Registering custom runtimes]
:::

:::{versionadded} 1.5.0
:::
""",
        ),
        "patch_strip": attr.int(
            mandatory = False,
            doc = "Same as the --strip argument of Unix patch.",
            default = 0,
        ),
        "patches": attr.label_list(
            mandatory = False,
            doc = "A list of labels pointing to patch files to apply for the interpreter repository. They are applied in the list order and are applied after the common patches are applied.",
        ),
        "platform": attr.string(
            mandatory = True,
            doc = """
The platform to override the values for, typically one of:\n
{platforms}

Other values are allowed, in which case, `target_compatible_with`,
`target_settings`, `os_name`, and `arch` should be specified so the toolchain is
only used when appropriate.

:::{{versionchanged}} 1.5.0
Arbitrary platform strings allowed.
:::
""".format(
                platforms = "\n".join(sorted(["* `{}`".format(p) for p in PLATFORMS])),
            ),
        ),
        "python_version": attr.string(
            mandatory = True,
            doc = "The python version to override URLs for. Must be in `X.Y.Z` format.",
        ),
        "sha256": attr.string(
            mandatory = False,
            doc = "The sha256 for the archive",
        ),
        "strip_prefix": attr.string(
            mandatory = False,
            doc = "The 'strip_prefix' for the archive, defaults to 'python'.",
            default = "python",
        ),
        "target_compatible_with": attr.string_list(
            doc = """
The `target_compatible_with` values to use for the toolchain definition.

If not set, then `os_name` and `arch` will be used to populate it.

If set, `target_settings`, `os_name`, and `arch` should also be set.

:::{seealso}
Docs for [Registering custom runtimes]
:::

:::{versionadded} 1.5.0
:::
""",
        ),
        "target_settings": attr.string_list(
            doc = """
The `target_setings` values to use for the toolchain definition.

If set, `target_compatible_with`, `os_name`, and `arch` should also be set.

:::{seealso}
Docs for [Registering custom runtimes]
:::

:::{versionadded} 1.5.0
:::
""",
        ),
        "urls": attr.string_list(
            mandatory = False,
            doc = "The URL template to fetch releases for this Python version. If the URL template results in a relative fragment, default base URL is going to be used. Occurrences of `{python_version}`, `{platform}` and `{build}` will be interpolated based on the contents in the override and the known {attr}`platform` values.",
        ),
    },
)

python = module_extension(
    doc = """Bzlmod extension that is used to register Python toolchains.
""",
    implementation = _python_impl,
    tag_classes = {
        "defaults": _defaults,
        "override": _override,
        "single_version_override": _single_version_override,
        "single_version_platform_override": _single_version_platform_override,
        "toolchain": _toolchain,
    },
    environ = ["RULES_PYTHON_BZLMOD_DEBUG"],
    os_dependent = True,
    arch_dependent = True,
)

_DEBUG_BUILD_CONTENT = """
package(
    default_visibility = ["//visibility:public"],
)
exports_files(["debug_info.json"])
"""

def _debug_repo_impl(repo_ctx):
    repo_ctx.file("BUILD.bazel", _DEBUG_BUILD_CONTENT)
    repo_ctx.file("debug_info.json", repo_ctx.attr.debug_info)

_debug_repo = repository_rule(
    implementation = _debug_repo_impl,
    attrs = {
        "debug_info": attr.string(),
    },
)
