-
-
Notifications
You must be signed in to change notification settings - Fork 583
feat: add support for passing extra pip args by platform #2745
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,65 @@ | ||||||||||
# 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. | ||||||||||
|
||||||||||
"" | ||||||||||
|
||||||||||
def _get_extra_pip_args_for_platform(ctx, extra_pip_args): | ||||||||||
"""Returns the pip args for the given platform from the dict. | ||||||||||
|
||||||||||
Args: | ||||||||||
ctx: Current repository context. | ||||||||||
extra_pip_args: (string keyed string list dict): Extra pip arguments. | ||||||||||
|
||||||||||
Returns: | ||||||||||
List of arguments for the current platform. | ||||||||||
""" | ||||||||||
|
||||||||||
os = ctx.os.name.replace(" ", "") | ||||||||||
arch = ctx.os.arch.replace(" ", "") | ||||||||||
Comment on lines
+28
to
+29
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
This is duplicating code from |
||||||||||
|
||||||||||
# Check if there's an exact match. | ||||||||||
full_match = "{}_{}".format(os, arch) | ||||||||||
if full_match in extra_pip_args: | ||||||||||
return extra_pip_args[full_match] | ||||||||||
|
||||||||||
# Match on the os. | ||||||||||
os_match = "{}_*".format(os) | ||||||||||
if os_match in extra_pip_args: | ||||||||||
return extra_pip_args[os_match] | ||||||||||
|
||||||||||
# Match on the arch. | ||||||||||
arch_match = "*_{}".format(arch) | ||||||||||
if arch_match in extra_pip_args: | ||||||||||
return extra_pip_args[arch_match] | ||||||||||
|
||||||||||
# Wildcard match last to allow for a more specific match. | ||||||||||
if "*" in extra_pip_args: | ||||||||||
return extra_pip_args["*"] | ||||||||||
|
||||||||||
return [] | ||||||||||
|
||||||||||
def resolve_extra_pip_args(ctx, extra_pip_args, extra_pip_args_by_platform): | ||||||||||
"""Resolves the given set of extra pip args to the list that should be used on the current platform. | ||||||||||
|
||||||||||
Args: | ||||||||||
ctx: Current repository or module context. | ||||||||||
extra_pip_args: (string list): Extra pip arguments. | ||||||||||
extra_pip_args_by_platform: (string keyed string list dict): Extra pip arguments keyed by platform. | ||||||||||
|
||||||||||
Returns: | ||||||||||
List of arguments for the current platform. | ||||||||||
""" | ||||||||||
if len(extra_pip_args_by_platform): | ||||||||||
return _get_extra_pip_args_for_platform(ctx, extra_pip_args_by_platform) | ||||||||||
return extra_pip_args |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,6 +20,7 @@ load("//python/private:repo_utils.bzl", "REPO_DEBUG_ENV_VAR") | |
load("//python/private:text_util.bzl", "render") | ||
load(":evaluate_markers.bzl", "evaluate_markers") | ||
load(":parse_requirements.bzl", "host_platform", "parse_requirements", "select_requirement") | ||
load(":pip_args.bzl", "resolve_extra_pip_args") | ||
load(":pip_repository_attrs.bzl", "ATTRS") | ||
load(":render_pkg_aliases.bzl", "render_pkg_aliases") | ||
load(":requirements_files_by_platform.bzl", "requirements_files_by_platform") | ||
|
@@ -71,6 +72,8 @@ exports_files(["requirements.bzl"]) | |
""" | ||
|
||
def _pip_repository_impl(rctx): | ||
extra_pip_args = resolve_extra_pip_args(rctx, rctx.attr.extra_pip_args, rctx.attr.extra_pip_args_by_platform) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do I understand correctly that this will resolve the pip args depending on the host platform? What about resolving based on the target platform? I'd rather pass the The current API is somewhat not great at doing the overrides per platform because we need to have these dictionaries for the overrides and if we add this, then we'll have to maintain this until v2. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you get the target platform in this context? The way The use case we have here is that we need to force binary only fetching on certain platforms, where as on others we can't do that and allow the sdist to be built. There are some other flags we pass only on Linux too, but I don't recall them, can check tomorrow. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I created #2747 to create a better API for this, but in the mean time this is how I can see things fit:
|
||
|
||
requirements_by_platform = parse_requirements( | ||
rctx, | ||
requirements_by_platform = requirements_files_by_platform( | ||
|
@@ -79,9 +82,9 @@ def _pip_repository_impl(rctx): | |
requirements_lock = rctx.attr.requirements_lock, | ||
requirements_osx = rctx.attr.requirements_darwin, | ||
requirements_windows = rctx.attr.requirements_windows, | ||
extra_pip_args = rctx.attr.extra_pip_args, | ||
extra_pip_args = extra_pip_args, | ||
), | ||
extra_pip_args = rctx.attr.extra_pip_args, | ||
extra_pip_args = extra_pip_args, | ||
evaluate_markers = evaluate_markers, | ||
) | ||
selected_requirements = {} | ||
|
Original file line number | Diff line number | Diff line change | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -21,6 +21,21 @@ repositories.""" | |||||||||||
load(":attrs.bzl", COMMON_ATTRS = "ATTRS") | ||||||||||||
|
||||||||||||
ATTRS = { | ||||||||||||
"extra_pip_args_by_platform": attr.string_list_dict( | ||||||||||||
doc = """Similar to `extra_pip_args`. | ||||||||||||
|
||||||||||||
Extra arguments to pass on to pip on the assoicated platform specifiers. Args must not contain spaces. | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you please update https://github.com/bazel-contrib/rules_python/blob/main/docs/pypi-dependencies.md?plain=1#L320 section on how this feature could be used? |
||||||||||||
|
||||||||||||
The keys in the dict take the form `<os>_<cpu>`, wildcards in the form `<os>_*` are supported. | ||||||||||||
Key values are as those returned in Bazels `repository_os` struct, with spaces removed. | ||||||||||||
|
||||||||||||
Supports environment variables using the syntax `$VARNAME` or | ||||||||||||
`${VARNAME}` (expanding to empty string if unset) or | ||||||||||||
`${VARNAME:-default}` (expanding to default if the variable is unset | ||||||||||||
or empty in the environment), if `"VARNAME"` is listed in the | ||||||||||||
`envsubst` attribute. See also `envsubst`. | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add a note when this has been added and we can link to the attributes in our docs.
Suggested change
|
||||||||||||
""", | ||||||||||||
), | ||||||||||||
"requirements_by_platform": attr.label_keyed_string_dict( | ||||||||||||
doc = """\ | ||||||||||||
The requirements files and the comma delimited list of target platforms as values. | ||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,12 +22,12 @@ load("//python/private/pypi:whl_config_setting.bzl", "whl_config_setting") # bu | |
|
||
_tests = [] | ||
|
||
def _mock_mctx(*modules, environ = {}, read = None): | ||
def _mock_mctx(*modules, environ = {}, os_name = "unittest", os_arch = "exotic", read = None): | ||
return struct( | ||
os = struct( | ||
environ = environ, | ||
name = "unittest", | ||
arch = "exotic", | ||
name = os_name, | ||
arch = os_arch, | ||
), | ||
read = read or (lambda _: """\ | ||
simple==0.0.1 \ | ||
|
@@ -49,7 +49,7 @@ simple==0.0.1 \ | |
], | ||
) | ||
|
||
def _mod(*, name, parse = [], override = [], whl_mods = [], is_root = True): | ||
def _mod(*, name, parse = [], override = [], whl_mods = [], is_root = True, os = {}): | ||
return struct( | ||
name = name, | ||
tags = struct( | ||
|
@@ -58,6 +58,7 @@ def _mod(*, name, parse = [], override = [], whl_mods = [], is_root = True): | |
whl_mods = whl_mods, | ||
), | ||
is_root = is_root, | ||
os = os, | ||
) | ||
|
||
def _parse_modules(env, **kwargs): | ||
|
@@ -87,6 +88,7 @@ def _parse( | |
experimental_target_platforms = [], | ||
extra_hub_aliases = {}, | ||
extra_pip_args = [], | ||
extra_pip_args_by_platform = {}, | ||
isolated = True, | ||
netrc = None, | ||
parse_all_requirements_files = True, | ||
|
@@ -115,6 +117,7 @@ def _parse( | |
experimental_target_platforms = experimental_target_platforms, | ||
extra_hub_aliases = extra_hub_aliases, | ||
extra_pip_args = extra_pip_args, | ||
extra_pip_args_by_platform = extra_pip_args_by_platform, | ||
hub_name = hub_name, | ||
isolated = isolated, | ||
netrc = netrc, | ||
|
@@ -182,6 +185,46 @@ def _test_simple(env): | |
|
||
_tests.append(_test_simple) | ||
|
||
def _test_simple_platform_pip_args(env): | ||
pypi = _parse_modules( | ||
env, | ||
module_ctx = _mock_mctx( | ||
_mod( | ||
name = "rules_python", | ||
parse = [ | ||
_parse( | ||
hub_name = "pypi", | ||
python_version = "3.15", | ||
requirements_darwin = "darwin.txt", | ||
extra_pip_args_by_platform = { | ||
"macosx_*": ["--only-binary=simple"], | ||
}, | ||
), | ||
], | ||
), | ||
os_name = "mac os x", | ||
os_arch = "arch64", | ||
read = lambda x: { | ||
"darwin.txt": "simple==0.0.2 --hash=sha256:deadb00f", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you please add extra files so that we can see that there are differences on each platform? |
||
}[x], | ||
), | ||
available_interpreters = { | ||
"python_3_15_host": "unit_test_interpreter_target", | ||
}, | ||
) | ||
|
||
pypi.whl_libraries().contains_exactly({ | ||
"pypi_315_simple": { | ||
"dep_template": "@pypi//{name}:{target}", | ||
"extra_pip_args": ["--only-binary=simple"], | ||
"python_interpreter_target": "unit_test_interpreter_target", | ||
"repo": "pypi_315", | ||
"requirement": "simple==0.0.2 --hash=sha256:deadb00f", | ||
}, | ||
}) | ||
|
||
_tests.append(_test_simple_platform_pip_args) | ||
|
||
def _test_simple_multiple_requirements(env): | ||
pypi = _parse_modules( | ||
env, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The pre-commit hook updated this 🤷