Skip to content

Commit ee34409

Browse files
authored
fix(pypi): call python --version before marker eval (#2819)
`bzlmod` has the full python version information statically and we don't need to call Python to get its version, but for `WORKSPACE` that is not the case and we have to call it before evaluating the markers in universal requirements files. This also fixes transitions in the `compile_pip_requirements` macro where the `.update` target would not transition correctly based on the `python_version` parameter. Fixes #2818
1 parent 1e21dbd commit ee34409

File tree

9 files changed

+37
-9
lines changed

9 files changed

+37
-9
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,10 @@ END_UNRELEASED_TEMPLATE
151151
* (pypi) Correctly handle `METADATA` entries when `python_full_version` is used in
152152
the environment marker.
153153
Fixes [#2319](https://github.com/bazel-contrib/rules_python/issues/2319).
154+
* (pypi) Correctly handle `python_version` parameter and transition the requirement
155+
locking to the right interpreter version when using
156+
{obj}`compile_pip_requirements` rule.
157+
See [#2819](https://github.com/bazel-contrib/rules_python/pull/2819).
154158

155159
{#1-4-0-added}
156160
### Added
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
websockets
1+
websockets ; python_full_version > "3.9.1"

examples/multi_python_versions/requirements/requirements_lock_3_10.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#
55
# bazel run //requirements:requirements_3_10.update
66
#
7-
websockets==11.0.3 \
7+
websockets==11.0.3 ; python_full_version > "3.9.1" \
88
--hash=sha256:01f5567d9cf6f502d655151645d4e8b72b453413d3819d2b6f1185abc23e82dd \
99
--hash=sha256:03aae4edc0b1c68498f41a6772d80ac7c1e33c06c6ffa2ac1c27a07653e79d6f \
1010
--hash=sha256:0ac56b661e60edd453585f4bd68eb6a29ae25b5184fd5ba51e97652580458998 \

examples/multi_python_versions/requirements/requirements_lock_3_11.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#
55
# bazel run //requirements:requirements_3_11.update
66
#
7-
websockets==11.0.3 \
7+
websockets==11.0.3 ; python_full_version > "3.9.1" \
88
--hash=sha256:01f5567d9cf6f502d655151645d4e8b72b453413d3819d2b6f1185abc23e82dd \
99
--hash=sha256:03aae4edc0b1c68498f41a6772d80ac7c1e33c06c6ffa2ac1c27a07653e79d6f \
1010
--hash=sha256:0ac56b661e60edd453585f4bd68eb6a29ae25b5184fd5ba51e97652580458998 \

examples/multi_python_versions/requirements/requirements_lock_3_9.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#
55
# bazel run //requirements:requirements_3_9.update
66
#
7-
websockets==11.0.3 \
7+
websockets==11.0.3 ; python_full_version > "3.9.1" \
88
--hash=sha256:01f5567d9cf6f502d655151645d4e8b72b453413d3819d2b6f1185abc23e82dd \
99
--hash=sha256:03aae4edc0b1c68498f41a6772d80ac7c1e33c06c6ffa2ac1c27a07653e79d6f \
1010
--hash=sha256:0ac56b661e60edd453585f4bd68eb6a29ae25b5184fd5ba51e97652580458998 \

python/private/pypi/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,7 @@ bzl_library(
283283
":evaluate_markers_bzl",
284284
":parse_requirements_bzl",
285285
":pip_repository_attrs_bzl",
286+
":pypi_repo_utils_bzl",
286287
":render_pkg_aliases_bzl",
287288
":whl_config_setting_bzl",
288289
"//python/private:normalize_name_bzl",

python/private/pypi/evaluate_markers.bzl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,12 @@ load(":pep508_evaluate.bzl", "evaluate")
1919
load(":pep508_platform.bzl", "platform_from_str")
2020
load(":pep508_requirement.bzl", "requirement")
2121

22-
def evaluate_markers(requirements):
22+
def evaluate_markers(requirements, python_version = None):
2323
"""Return the list of supported platforms per requirements line.
2424
2525
Args:
26-
requirements: dict[str, list[str]] of the requirement file lines to evaluate.
26+
requirements: {type}`dict[str, list[str]]` of the requirement file lines to evaluate.
27+
python_version: {type}`str | None` the version that can be used when evaluating the markers.
2728
2829
Returns:
2930
dict of string lists with target platforms
@@ -32,7 +33,7 @@ def evaluate_markers(requirements):
3233
for req_string, platforms in requirements.items():
3334
req = requirement(req_string)
3435
for platform in platforms:
35-
if evaluate(req.marker, env = env(platform_from_str(platform, None))):
36+
if evaluate(req.marker, env = env(platform_from_str(platform, python_version))):
3637
ret.setdefault(req_string, []).append(platform)
3738

3839
return ret

python/private/pypi/pip_compile.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ def pip_compile(
160160
py_binary(
161161
name = name + ".update",
162162
env = env,
163+
python_version = kwargs.get("python_version", None),
163164
**attrs
164165
)
165166

python/private/pypi/pip_repository.bzl

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@
1616

1717
load("@bazel_skylib//lib:sets.bzl", "sets")
1818
load("//python/private:normalize_name.bzl", "normalize_name")
19-
load("//python/private:repo_utils.bzl", "REPO_DEBUG_ENV_VAR")
19+
load("//python/private:repo_utils.bzl", "REPO_DEBUG_ENV_VAR", "repo_utils")
2020
load("//python/private:text_util.bzl", "render")
2121
load(":evaluate_markers.bzl", "evaluate_markers")
2222
load(":parse_requirements.bzl", "host_platform", "parse_requirements", "select_requirement")
2323
load(":pip_repository_attrs.bzl", "ATTRS")
24+
load(":pypi_repo_utils.bzl", "pypi_repo_utils")
2425
load(":render_pkg_aliases.bzl", "render_pkg_aliases")
2526
load(":requirements_files_by_platform.bzl", "requirements_files_by_platform")
2627

@@ -70,7 +71,27 @@ package(default_visibility = ["//visibility:public"])
7071
exports_files(["requirements.bzl"])
7172
"""
7273

74+
def _evaluate_markers(rctx, requirements, logger = None):
75+
python_interpreter = _get_python_interpreter_attr(rctx)
76+
stdout = pypi_repo_utils.execute_checked_stdout(
77+
rctx,
78+
op = "GetPythonVersionForMarkerEval",
79+
python = python_interpreter,
80+
arguments = [
81+
# Run the interpreter in isolated mode, this options implies -E, -P and -s.
82+
# Ensures environment variables are ignored that are set in userspace, such as PYTHONPATH,
83+
# which may interfere with this invocation.
84+
"-I",
85+
"-c",
86+
"import sys; print(f'{sys.version_info[0]}.{sys.version_info[1]}.{sys.version_info[2]}', end='')",
87+
],
88+
srcs = [],
89+
logger = logger,
90+
)
91+
return evaluate_markers(requirements, python_version = stdout)
92+
7393
def _pip_repository_impl(rctx):
94+
logger = repo_utils.logger(rctx)
7495
requirements_by_platform = parse_requirements(
7596
rctx,
7697
requirements_by_platform = requirements_files_by_platform(
@@ -82,7 +103,7 @@ def _pip_repository_impl(rctx):
82103
extra_pip_args = rctx.attr.extra_pip_args,
83104
),
84105
extra_pip_args = rctx.attr.extra_pip_args,
85-
evaluate_markers = evaluate_markers,
106+
evaluate_markers = lambda requirements: _evaluate_markers(rctx, requirements, logger),
86107
)
87108
selected_requirements = {}
88109
options = None

0 commit comments

Comments
 (0)