Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion gazelle/python/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
24 changes: 23 additions & 1 deletion python/private/config_settings.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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),
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need targets that are for other Python versions, but maybe instead of this hack to make the versions incompatible, we colud do it differently:

for minor in range("3.0", max(minor_mapping)):
    native.config_setting()

That way we'll get the right behaviour. Another option would be to leave minor_mapping[3.8] = None. That way we might get the right behaviour as well.

actual = "@platforms//:incompatible",
visibility = ["//visibility:public"],
)

_current_config(
name = "current_config",
build_setting_default = "",
Expand Down
5 changes: 4 additions & 1 deletion python/private/full_version.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -31,6 +32,8 @@ def full_version(*, version, minor_mapping):
parts = version.split(".")
if len(parts) == 3:
return version
elif not err:
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: unit test

return None
elif len(parts) == 2:
fail(
"Unknown Python version '{}', available values are: {}".format(
Expand Down
27 changes: 20 additions & 7 deletions python/private/pypi/hub_builder.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: unit test this.

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)
Expand Down Expand Up @@ -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,
)

Expand Down
5 changes: 5 additions & 0 deletions python/private/python.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
12 changes: 0 additions & 12 deletions python/versions.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -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.10": {
"url": "20220227/cpython-{python_version}+20220227-{platform}-{build}.tar.gz",
"sha256": {
Expand Down Expand Up @@ -1011,7 +1000,6 @@ TOOL_VERSIONS = {

# buildifier: disable=unsorted-dict-items
MINOR_MAPPING = {
"3.8": "3.8.20",
"3.9": "3.9.24",
"3.10": "3.10.19",
"3.11": "3.11.14",
Expand Down