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: 1 addition & 0 deletions .bazelrc.deleted_packages
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ common --deleted_packages=tests/integration/custom_commands
common --deleted_packages=tests/integration/local_toolchains
common --deleted_packages=tests/integration/pip_parse
common --deleted_packages=tests/integration/pip_parse/empty
common --deleted_packages=tests/integration/pip_parse_isolated
common --deleted_packages=tests/integration/py_cc_toolchain_registered
common --deleted_packages=tests/modules/another_module
common --deleted_packages=tests/modules/other
Expand Down
134 changes: 0 additions & 134 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -65,140 +65,6 @@ register_toolchains("@pythons_hub//:all")

pip = use_extension("//python/extensions:pip.bzl", "pip")

# NOTE @aignas 2025-07-06: we define these platforms to keep backwards compatibility. Whilst we
# stabilize the API this list may be updated with a mention in the CHANGELOG.
[
pip.default(
arch_name = cpu,
config_settings = [
"@platforms//cpu:{}".format(cpu),
"@platforms//os:linux",
"//python/config_settings:_is_py_freethreaded_{}".format(
"yes" if freethreaded else "no",
),
],
env = {"platform_version": "0"},
marker = "python_version >= '3.13'" if freethreaded else "",
os_name = "linux",
platform = "linux_{}{}".format(cpu, freethreaded),
whl_abi_tags = ["cp{major}{minor}t"] if freethreaded else [
"abi3",
"cp{major}{minor}",
],
whl_platform_tags = [
"linux_{}".format(cpu),
"manylinux_*_{}".format(cpu),
],
)
for cpu in [
"x86_64",
"aarch64",
]
for freethreaded in [
"",
"_freethreaded",
]
]

[
pip.default(
arch_name = cpu,
config_settings = [
"@platforms//cpu:{}".format(cpu),
"@platforms//os:osx",
"//python/config_settings:_is_py_freethreaded_{}".format(
"yes" if freethreaded else "no",
),
],
# We choose the oldest non-EOL version at the time when we release `rules_python`.
# See https://endoflife.date/macos
env = {"platform_version": "14.0"},
marker = "python_version >= '3.13'" if freethreaded else "",
os_name = "osx",
platform = "osx_{}{}".format(cpu, freethreaded),
whl_abi_tags = ["cp{major}{minor}t"] if freethreaded else [
"abi3",
"cp{major}{minor}",
],
whl_platform_tags = [
"macosx_*_{}".format(suffix)
for suffix in platform_tag_cpus
],
)
for cpu, platform_tag_cpus in {
"aarch64": [
"universal2",
"arm64",
],
"x86_64": [
"universal2",
"x86_64",
],
}.items()
for freethreaded in [
"",
"_freethreaded",
]
]

[
pip.default(
arch_name = cpu,
config_settings = [
"@platforms//cpu:{}".format(cpu),
"@platforms//os:windows",
"//python/config_settings:_is_py_freethreaded_{}".format(
"yes" if freethreaded else "no",
),
],
env = {"platform_version": "0"},
marker = "python_version >= '3.13'" if freethreaded else "",
os_name = "windows",
platform = "windows_{}{}".format(cpu, freethreaded),
whl_abi_tags = ["cp{major}{minor}t"] if freethreaded else [
"abi3",
"cp{major}{minor}",
],
whl_platform_tags = whl_platform_tags,
)
for cpu, whl_platform_tags in {
"x86_64": ["win_amd64"],
}.items()
for freethreaded in [
"",
"_freethreaded",
]
]

[
pip.default(
arch_name = cpu,
config_settings = [
"@platforms//cpu:{}".format(cpu),
"@platforms//os:windows",
"//python/config_settings:_is_py_freethreaded_{}".format(
"yes" if freethreaded else "no",
),
],
env = {"platform_version": "0"},
marker = "python_version >= '3.13'" if freethreaded else "python_version >= '3.11'",
os_name = "windows",
platform = "windows_{}{}".format(cpu, freethreaded),
whl_abi_tags = ["cp{major}{minor}t"] if freethreaded else [
"abi3",
"cp{major}{minor}",
],
whl_platform_tags = whl_platform_tags,
)
for cpu, whl_platform_tags in {
"aarch64": ["win_arm64"],
}.items()
for freethreaded in [
"",
"_freethreaded",
]
]

pip.parse(
hub_name = "rules_python_publish_deps",
python_version = "3.11",
Expand Down
124 changes: 123 additions & 1 deletion python/private/pypi/extension.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,128 @@ def _whl_mods_impl(whl_mods_dict):
whl_mods = whl_mods,
)

def default_platforms():
"""Return the built-in default platform definitions.

These provide the platform metadata needed for pip wheel resolution
(whl_abi_tags, whl_platform_tags, config_settings, etc.) across all
common OS/arch combinations. They are always used as the starting point
for build_config; root modules can override individual platforms via
pip.default tags.

Returns:
A dict of platform name to platform config dicts.
"""
# NOTE @aignas 2025-07-06: we define these platforms to keep backwards compatibility. Whilst we
# stabilize the API this list may be updated with a mention in the CHANGELOG.

platforms = {}

# Linux platforms
for cpu in ["x86_64", "aarch64"]:
for freethreaded in ["", "_freethreaded"]:
platform_name = "linux_{}{}".format(cpu, freethreaded)
platforms[platform_name] = {
"arch_name": cpu,
"config_settings": [
"@platforms//cpu:{}".format(cpu),
"@platforms//os:linux",
"//python/config_settings:_is_py_freethreaded_{}".format(
"yes" if freethreaded else "no",
),
],
"env": {"platform_version": "0"},
"marker": "python_version >= '3.13'" if freethreaded else "",
"name": platform_name,
"os_name": "linux",
"whl_abi_tags": ["cp{major}{minor}t"] if freethreaded else [
"abi3",
"cp{major}{minor}",
],
"whl_platform_tags": [
"linux_{}".format(cpu),
"manylinux_*_{}".format(cpu),
],
}

# macOS platforms
for cpu, platform_tag_cpus in {
"aarch64": ["universal2", "arm64"],
"x86_64": ["universal2", "x86_64"],
}.items():
for freethreaded in ["", "_freethreaded"]:
platform_name = "osx_{}{}".format(cpu, freethreaded)
platforms[platform_name] = {
"arch_name": cpu,
"config_settings": [
"@platforms//cpu:{}".format(cpu),
"@platforms//os:osx",
"//python/config_settings:_is_py_freethreaded_{}".format(
"yes" if freethreaded else "no",
),
],
"env": {"platform_version": "14.0"},
"marker": "python_version >= '3.13'" if freethreaded else "",
"name": platform_name,
"os_name": "osx",
"whl_abi_tags": ["cp{major}{minor}t"] if freethreaded else [
"abi3",
"cp{major}{minor}",
],
"whl_platform_tags": [
"macosx_*_{}".format(suffix)
for suffix in platform_tag_cpus
],
}

# Windows x86_64 platforms
for freethreaded in ["", "_freethreaded"]:
platform_name = "windows_x86_64{}".format(freethreaded)
platforms[platform_name] = {
"arch_name": "x86_64",
"config_settings": [
"@platforms//cpu:x86_64",
"@platforms//os:windows",
"//python/config_settings:_is_py_freethreaded_{}".format(
"yes" if freethreaded else "no",
),
],
"env": {"platform_version": "0"},
"marker": "python_version >= '3.13'" if freethreaded else "",
"name": platform_name,
"os_name": "windows",
"whl_abi_tags": ["cp{major}{minor}t"] if freethreaded else [
"abi3",
"cp{major}{minor}",
],
"whl_platform_tags": ["win_amd64"],
}

# Windows aarch64 platforms
for freethreaded in ["", "_freethreaded"]:
platform_name = "windows_aarch64{}".format(freethreaded)
platforms[platform_name] = {
"arch_name": "aarch64",
"config_settings": [
"@platforms//cpu:aarch64",
"@platforms//os:windows",
"//python/config_settings:_is_py_freethreaded_{}".format(
"yes" if freethreaded else "no",
),
],
"env": {"platform_version": "0"},
"marker": "python_version >= '3.13'" if freethreaded else "python_version >= '3.11'",
"name": platform_name,
"os_name": "windows",
"whl_abi_tags": ["cp{major}{minor}t"] if freethreaded else [
"abi3",
"cp{major}{minor}",
],
"whl_platform_tags": ["win_arm64"],
}

return platforms

def _configure(config, *, override = False, **kwargs):
"""Set the value in the config if the value is provided"""
env = kwargs.get("env")
Expand Down Expand Up @@ -86,7 +208,7 @@ def build_config(
A struct with the configuration.
"""
defaults = {
"platforms": {},
"platforms": default_platforms(),
}
for mod in module_ctx.modules:
if not (mod.is_root or mod.name == "rules_python"):
Expand Down
4 changes: 4 additions & 0 deletions tests/integration/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ rules_python_integration_test(
name = "pip_parse_test",
)

rules_python_integration_test(
name = "pip_parse_isolated_test",
)

rules_python_integration_test(
name = "pip_parse_workspace_test",
bzlmod = False,
Expand Down
8 changes: 8 additions & 0 deletions tests/integration/pip_parse_isolated/.bazelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Bazel configuration flags

build --enable_runfiles

common --experimental_isolated_extension_usages

# https://docs.bazel.build/versions/main/best-practices.html#using-the-bazelrc-file
try-import %workspace%/user.bazelrc
7 changes: 7 additions & 0 deletions tests/integration/pip_parse_isolated/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
load("@rules_python//python:py_test.bzl", "py_test")

py_test(
name = "test_isolated",
srcs = ["test_isolated.py"],
deps = ["@pypi//six"],
)
19 changes: 19 additions & 0 deletions tests/integration/pip_parse_isolated/MODULE.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module(name = "pip_parse_isolated")

bazel_dep(name = "rules_python")
local_path_override(
module_name = "rules_python",
path = "../../..",
)

python = use_extension("@rules_python//python/extensions:python.bzl", "python")
python.toolchain(python_version = "3.13")

# This test module verifies that dependencies can be used with `isolate = True`.
pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip", isolate = True)
pip.parse(
hub_name = "pypi",
python_version = "3.13",
requirements_lock = "//:requirements_lock.txt",
)
use_repo(pip, "pypi")
Empty file.
2 changes: 2 additions & 0 deletions tests/integration/pip_parse_isolated/requirements_lock.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
six==1.17.0 \
--hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274
16 changes: 16 additions & 0 deletions tests/integration/pip_parse_isolated/test_isolated.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"""
Verify that a dependency added using an isolated extension can be imported.
See MODULE.bazel.
"""

import six
import unittest


class TestIsolated(unittest.TestCase):
def test_import(self):
self.assertTrue(hasattr(six, "PY3"))


if __name__ == "__main__":
unittest.main()
Loading