Skip to content

WIP: a builder API for pip extension 1/n - platform defs #2909

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 14 commits into
base: main
Choose a base branch
from
Draft
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ END_UNRELEASED_TEMPLATE
Set the `RULES_PYTHON_ENABLE_PIPSTAR=1` environment variable to enable it.
* (utils) Add a way to run a REPL for any `rules_python` target that returns
a `PyInfo` provider.
* (pypi) Added early developer preview `pip.default` tag class in order to customize what
platforms are enabled. Only `rules_python` and root modules can use this feature.

{#v0-0-0-removed}
### Removed
Expand Down
64 changes: 62 additions & 2 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,70 @@ use_repo(
# This call registers the Python toolchains.
register_toolchains("@pythons_hub//:all")

# Let's define default platforms for our users first
pip = use_extension("//python/extensions:pip.bzl", "pip")

_DEFAULT_LINUX_PLATFORM_VERSION = "0"

_DEFAULT_OSX_PLATFORM_VERSION = "14.0"

_DEFAULT_WINDOWS_PLATFORM_VERSION = "0"

[
pip.default(
arch_name = cpu,
constraint_values = [
"@platforms//os:linux",
"@platforms//cpu:{}".format(cpu),
],
env_platform_version = _DEFAULT_LINUX_PLATFORM_VERSION,
os_name = "linux",
platform = "linux_{}".format(cpu),
)
# TODO @aignas 2025-05-19: only leave tier 0-1 cpus when stabilizing the
# `pip.default` extension
for cpu in [
"aarch64",
"arm",
"ppc",
"s390x",
"x86_64",
]
]

[
pip.default(
arch_name = cpu,
constraint_values = [
"@platforms//os:osx",
"@platforms//cpu:{}".format(cpu),
],
# We choose the oldest non-EOL version at the time when we release `rules_python`.
# See https://endoflife.date/macos
env_platform_version = _DEFAULT_OSX_PLATFORM_VERSION,
os_name = "osx",
platform = "osx_{}".format(cpu),
)
for cpu in [
"aarch64",
"x86_64",
]
]

pip.default(
arch_name = "x86_64",
constraint_values = [
"@platforms//os:windows",
"@platforms//cpu:x86_64",
],
env_platform_version = _DEFAULT_WINDOWS_PLATFORM_VERSION,
os_name = "windows",
platform = "windows_x86_64",
)

#####################
# Install twine for our own runfiles wheel publishing and allow bzlmod users to use it.
# Then install twine for our own runfiles wheel publishing and allow bzlmod users to use it.

pip = use_extension("//python/extensions:pip.bzl", "pip")
pip.parse(
# NOTE @aignas 2024-10-26: We have an integration test that depends on us
# being able to build sdists for this hub, so explicitly set this to False.
Expand Down
18 changes: 10 additions & 8 deletions python/private/pypi/evaluate_markers.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@
"""A simple function that evaluates markers using a python interpreter."""

load(":deps.bzl", "record_files")
load(":pep508_env.bzl", "env")
load(":pep508_evaluate.bzl", "evaluate")
load(":pep508_platform.bzl", "platform_from_str")
load(":pep508_requirement.bzl", "requirement")
load(":pypi_repo_utils.bzl", "pypi_repo_utils")

Expand All @@ -30,22 +28,26 @@ SRCS = [
Label("//python/private/pypi/whl_installer:platform.py"),
]

def evaluate_markers(requirements, python_version = None):
def evaluate_markers(*, requirements, platforms):
"""Return the list of supported platforms per requirements line.

Args:
requirements: {type}`dict[str, list[str]]` of the requirement file lines to evaluate.
python_version: {type}`str | None` the version that can be used when evaluating the markers.
platforms: {type}`dict[str | struct]` TODO

Returns:
dict of string lists with target platforms
"""
ret = {}
for req_string, platforms in requirements.items():
for req_string, platform_strings in requirements.items():
req = requirement(req_string)
for platform in platforms:
if evaluate(req.marker, env = env(platform_from_str(platform, python_version))):
ret.setdefault(req_string, []).append(platform)
for platform_str in platform_strings:
env = platforms.get(platform_str)
if not env:
fail("Please define platform: '{}'".format(platform_str))

if evaluate(req.marker, env = env):
ret.setdefault(req_string, []).append(platform_str)

return ret

Expand Down
Loading