Skip to content

Commit 213a39c

Browse files
authored
Merge branch 'main' into fix/2434-repro
2 parents 1ab491e + 965dd51 commit 213a39c

36 files changed

+1455
-380
lines changed

CHANGELOG.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ Unreleased changes template.
5757
`exec_interpreter` now also forwards the `ToolchainInfo` provider. This is
5858
for increased compatibility with the `RBE` setups where access to the `exec`
5959
configuration interpreter is needed.
60-
* (toolchains) Use the latest astrahl-sh toolchain release [20250317] for Python versions:
60+
* (toolchains) Use the latest astral-sh toolchain release [20250317] for Python versions:
6161
* 3.9.21
6262
* 3.10.16
6363
* 3.11.11
@@ -84,6 +84,14 @@ Unreleased changes template.
8484

8585
{#v0-0-0-added}
8686
### Added
87+
* (pypi) From now on `sha256` values in the `requirements.txt` is no longer
88+
mandatory when enabling {attr}`pip.parse.experimental_index_url` feature.
89+
This means that `rules_python` will attempt to fetch metadata for all
90+
packages through SimpleAPI unless they are pulled through direct URL
91+
references. Fixes [#2023](https://github.com/bazel-contrib/rules_python/issues/2023).
92+
In case you see issues with `rules_python` being too eager to fetch the SimpleAPI
93+
metadata, you can use the newly added {attr}`pip.parse.experimental_skip_sources`
94+
to skip metadata fetching for those packages.
8795
* (uv) A {obj}`lock` rule that is the replacement for the
8896
{obj}`compile_pip_requirements`. This may still have rough corners
8997
so please report issues with it in the

docs/pypi-dependencies.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -386,11 +386,13 @@ This does not mean that `rules_python` is fetching the wheels eagerly, but it
386386
rather means that it is calling the PyPI server to get the Simple API response
387387
to get the list of all available source and wheel distributions. Once it has
388388
got all of the available distributions, it will select the right ones depending
389-
on the `sha256` values in your `requirements_lock.txt` file. The compatible
390-
distribution URLs will be then written to the `MODULE.bazel.lock` file. Currently
391-
users wishing to use the lock file with `rules_python` with this feature have
392-
to set an environment variable `RULES_PYTHON_OS_ARCH_LOCK_FILE=0` which will
393-
become default in the next release.
389+
on the `sha256` values in your `requirements_lock.txt` file. If `sha256` hashes
390+
are not present in the requirements file, we will fallback to matching by version
391+
specified in the lock file. The compatible distribution URLs will be then
392+
written to the `MODULE.bazel.lock` file. Currently users wishing to use the
393+
lock file with `rules_python` with this feature have to set an environment
394+
variable `RULES_PYTHON_OS_ARCH_LOCK_FILE=0` which will become default in the
395+
next release.
394396

395397
Fetching the distribution information from the PyPI allows `rules_python` to
396398
know which `whl` should be used on which target platform and it will determine

docs/requirements.txt

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ babel==2.17.0 \
1818
--hash=sha256:0c54cffb19f690cdcc52a3b50bcbf71e07a808d1c80d549f2459b9d2cf0afb9d \
1919
--hash=sha256:4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2
2020
# via sphinx
21-
certifi==2024.8.30 \
22-
--hash=sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8 \
23-
--hash=sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9
21+
certifi==2025.1.31 \
22+
--hash=sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651 \
23+
--hash=sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe
2424
# via requests
2525
charset-normalizer==3.4.0 \
2626
--hash=sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621 \
@@ -236,15 +236,15 @@ myst-parser==4.0.0 \
236236
--hash=sha256:851c9dfb44e36e56d15d05e72f02b80da21a9e0d07cba96baf5e2d476bb91531 \
237237
--hash=sha256:b9317997552424448c6096c2558872fdb6f81d3ecb3a40ce84a7518798f3f28d
238238
# via rules-python-docs (docs/pyproject.toml)
239-
packaging==24.1 \
240-
--hash=sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002 \
241-
--hash=sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124
239+
packaging==24.2 \
240+
--hash=sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759 \
241+
--hash=sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f
242242
# via
243243
# readthedocs-sphinx-ext
244244
# sphinx
245-
pygments==2.18.0 \
246-
--hash=sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199 \
247-
--hash=sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a
245+
pygments==2.19.1 \
246+
--hash=sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f \
247+
--hash=sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c
248248
# via sphinx
249249
pyyaml==6.0.2 \
250250
--hash=sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff \
@@ -328,9 +328,9 @@ sphinx-autodoc2==0.5.0 \
328328
--hash=sha256:7d76044aa81d6af74447080182b6868c7eb066874edc835e8ddf810735b6565a \
329329
--hash=sha256:e867013b1512f9d6d7e6f6799f8b537d6884462acd118ef361f3f619a60b5c9e
330330
# via rules-python-docs (docs/pyproject.toml)
331-
sphinx-reredirects==0.1.5 \
332-
--hash=sha256:444ae1438fba4418242ca76d6a6de3eaee82aaf0d8f2b0cac71a15d32ce6eba2 \
333-
--hash=sha256:cfa753b441020a22708ce8eb17d4fd553a28fc87a609330092917ada2a6da0d8
331+
sphinx-reredirects==0.1.6 \
332+
--hash=sha256:c491cba545f67be9697508727818d8626626366245ae64456fe29f37e9bbea64 \
333+
--hash=sha256:efd50c766fbc5bf40cd5148e10c00f2c00d143027de5c5e48beece93cc40eeea
334334
# via rules-python-docs (docs/pyproject.toml)
335335
sphinx-rtd-theme==3.0.1 \
336336
--hash=sha256:921c0ece75e90633ee876bd7b148cfaad136b481907ad154ac3669b6fc957916 \

python/private/BUILD.bazel

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ bzl_library(
7272
":py_internal_bzl",
7373
":reexports_bzl",
7474
":rules_cc_srcs_bzl",
75-
":semantics_bzl",
7675
"@bazel_skylib//rules:common_settings",
7776
],
7877
)
@@ -131,7 +130,6 @@ bzl_library(
131130
":py_internal_bzl",
132131
":reexports_bzl",
133132
":rules_cc_srcs_bzl",
134-
":semantics_bzl",
135133
"@bazel_skylib//lib:paths",
136134
],
137135
)
@@ -302,7 +300,6 @@ bzl_library(
302300
":attributes_bzl",
303301
":py_executable_bzl",
304302
":rule_builders_bzl",
305-
":semantics_bzl",
306303
"@bazel_skylib//lib:dicts",
307304
],
308305
)
@@ -537,7 +534,6 @@ bzl_library(
537534
":common_bzl",
538535
":py_executable_bzl",
539536
":rule_builders_bzl",
540-
":semantics_bzl",
541537
"@bazel_skylib//lib:dicts",
542538
],
543539
)
@@ -677,11 +673,6 @@ bzl_library(
677673
],
678674
)
679675

680-
bzl_library(
681-
name = "semantics_bzl",
682-
srcs = ["semantics.bzl"],
683-
)
684-
685676
# Needed to define bzl_library targets for docgen. (We don't define the
686677
# bzl_library target here because it'd give our users a transitive dependency
687678
# on Skylib.)

python/private/attributes.bzl

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,6 @@ load(":py_info.bzl", "PyInfo")
2323
load(":py_internal.bzl", "py_internal")
2424
load(":reexports.bzl", "BuiltinPyInfo")
2525
load(":rule_builders.bzl", "ruleb")
26-
load(
27-
":semantics.bzl",
28-
"DEPS_ATTR_ALLOW_RULES",
29-
"SRCS_ATTR_ALLOW_FILES",
30-
)
3126

3227
_PackageSpecificationInfo = getattr(py_internal, "PackageSpecificationInfo", None)
3328

@@ -250,9 +245,6 @@ PY_SRCS_ATTRS = dicts.add(
250245
[PyInfo],
251246
[CcInfo],
252247
] + _MaybeBuiltinPyInfo,
253-
# TODO(b/228692666): Google-specific; remove these allowances once
254-
# the depot is cleaned up.
255-
allow_rules = DEPS_ATTR_ALLOW_RULES,
256248
doc = """
257249
List of additional libraries to be linked in to the target.
258250
See comments about
@@ -359,8 +351,7 @@ as part of a runnable program (packaging rules may include them, however).
359351
allow_files = True,
360352
),
361353
"srcs": lambda: attrb.LabelList(
362-
# Google builds change the set of allowed files.
363-
allow_files = SRCS_ATTR_ALLOW_FILES,
354+
allow_files = [".py", ".py3"],
364355
# Necessary for --compile_one_dependency to work.
365356
flags = ["DIRECT_COMPILE_TIME_INPUT"],
366357
doc = """

python/private/py_executable.bzl

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,6 @@ load(":py_internal.bzl", "py_internal")
5959
load(":py_runtime_info.bzl", "DEFAULT_STUB_SHEBANG", "PyRuntimeInfo")
6060
load(":reexports.bzl", "BuiltinPyInfo", "BuiltinPyRuntimeInfo")
6161
load(":rule_builders.bzl", "ruleb")
62-
load(
63-
":semantics.bzl",
64-
"ALLOWED_MAIN_EXTENSIONS",
65-
"BUILD_DATA_SYMLINK_PATH",
66-
"IS_BAZEL",
67-
"PY_RUNTIME_ATTR_NAME",
68-
)
6962
load(
7063
":toolchain_types.bzl",
7164
"EXEC_TOOLS_TOOLCHAIN_TYPE",
@@ -1116,19 +1109,12 @@ def _get_runtime_details(ctx, semantics):
11161109
#
11171110
# TOOD(bazelbuild/bazel#7901): Remove this once --python_path flag is removed.
11181111

1119-
if IS_BAZEL:
1120-
flag_interpreter_path = ctx.fragments.bazel_py.python_path
1121-
toolchain_runtime, effective_runtime = _maybe_get_runtime_from_ctx(ctx)
1122-
if not effective_runtime:
1123-
# Clear these just in case
1124-
toolchain_runtime = None
1125-
effective_runtime = None
1126-
1127-
else: # Google code path
1128-
flag_interpreter_path = None
1129-
toolchain_runtime, effective_runtime = _maybe_get_runtime_from_ctx(ctx)
1130-
if not effective_runtime:
1131-
fail("Unable to find Python runtime")
1112+
flag_interpreter_path = ctx.fragments.bazel_py.python_path
1113+
toolchain_runtime, effective_runtime = _maybe_get_runtime_from_ctx(ctx)
1114+
if not effective_runtime:
1115+
# Clear these just in case
1116+
toolchain_runtime = None
1117+
effective_runtime = None
11321118

11331119
if effective_runtime:
11341120
direct = [] # List of files
@@ -1207,7 +1193,7 @@ def _maybe_get_runtime_from_ctx(ctx):
12071193
effective_runtime = toolchain_runtime
12081194
else:
12091195
toolchain_runtime = None
1210-
attr_target = getattr(ctx.attr, PY_RUNTIME_ATTR_NAME)
1196+
attr_target = ctx.attr._py_interpreter
12111197

12121198
# In Bazel, --python_top is null by default.
12131199
if attr_target and PyRuntimeInfo in attr_target:
@@ -1335,9 +1321,9 @@ def _create_runfiles_with_build_data(
13351321
central_uncachable_version_file,
13361322
extra_write_build_data_env,
13371323
)
1338-
build_data_runfiles = ctx.runfiles(symlinks = {
1339-
BUILD_DATA_SYMLINK_PATH: build_data_file,
1340-
})
1324+
build_data_runfiles = ctx.runfiles(files = [
1325+
build_data_file,
1326+
])
13411327
return build_data_file, build_data_runfiles
13421328

13431329
def _write_build_data(ctx, central_uncachable_version_file, extra_write_build_data_env):
@@ -1552,7 +1538,7 @@ def determine_main(ctx):
15521538
"""
15531539
if ctx.attr.main:
15541540
proposed_main = ctx.attr.main.label.name
1555-
if not proposed_main.endswith(tuple(ALLOWED_MAIN_EXTENSIONS)):
1541+
if not proposed_main.endswith(".py"):
15561542
fail("main must end in '.py'")
15571543
else:
15581544
if ctx.label.name.endswith(".py"):

python/private/pypi/BUILD.bazel

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,9 @@ bzl_library(
7575
name = "evaluate_markers_bzl",
7676
srcs = ["evaluate_markers.bzl"],
7777
deps = [
78-
":pypi_repo_utils_bzl",
78+
":pep508_env_bzl",
79+
":pep508_evaluate_bzl",
80+
":pep508_req_bzl",
7981
],
8082
)
8183

@@ -209,6 +211,37 @@ bzl_library(
209211
],
210212
)
211213

214+
bzl_library(
215+
name = "pep508_bzl",
216+
srcs = ["pep508.bzl"],
217+
deps = [
218+
":pep508_env_bzl",
219+
":pep508_evaluate_bzl",
220+
],
221+
)
222+
223+
bzl_library(
224+
name = "pep508_env_bzl",
225+
srcs = ["pep508_env.bzl"],
226+
)
227+
228+
bzl_library(
229+
name = "pep508_evaluate_bzl",
230+
srcs = ["pep508_evaluate.bzl"],
231+
deps = [
232+
"//python/private:enum_bzl",
233+
"//python/private:semver_bzl",
234+
],
235+
)
236+
237+
bzl_library(
238+
name = "pep508_req_bzl",
239+
srcs = ["pep508_req.bzl"],
240+
deps = [
241+
"//python/private:normalize_name_bzl",
242+
],
243+
)
244+
212245
bzl_library(
213246
name = "pip_bzl",
214247
srcs = ["pip.bzl"],

python/private/pypi/evaluate_markers.bzl

Lines changed: 13 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -14,65 +14,24 @@
1414

1515
"""A simple function that evaluates markers using a python interpreter."""
1616

17-
load(":deps.bzl", "record_files")
18-
load(":pypi_repo_utils.bzl", "pypi_repo_utils")
17+
load(":pep508_env.bzl", "env", _platform_from_str = "platform_from_str")
18+
load(":pep508_evaluate.bzl", "evaluate")
19+
load(":pep508_req.bzl", _req = "requirement")
1920

20-
# Used as a default value in a rule to ensure we fetch the dependencies.
21-
SRCS = [
22-
# When the version, or any of the files in `packaging` package changes,
23-
# this file will change as well.
24-
record_files["pypi__packaging"],
25-
Label("//python/private/pypi/requirements_parser:resolve_target_platforms.py"),
26-
Label("//python/private/pypi/whl_installer:platform.py"),
27-
]
28-
29-
def evaluate_markers(mrctx, *, requirements, python_interpreter, python_interpreter_target, srcs, logger = None):
21+
def evaluate_markers(requirements):
3022
"""Return the list of supported platforms per requirements line.
3123
3224
Args:
33-
mrctx: repository_ctx or module_ctx.
34-
requirements: list[str] of the requirement file lines to evaluate.
35-
python_interpreter: str, path to the python_interpreter to use to
36-
evaluate the env markers in the given requirements files. It will
37-
be only called if the requirements files have env markers. This
38-
should be something that is in your PATH or an absolute path.
39-
python_interpreter_target: Label, same as python_interpreter, but in a
40-
label format.
41-
srcs: list[Label], the value of SRCS passed from the `rctx` or `mctx` to this function.
42-
logger: repo_utils.logger or None, a simple struct to log diagnostic
43-
messages. Defaults to None.
25+
requirements: dict[str, list[str]] of the requirement file lines to evaluate.
4426
4527
Returns:
4628
dict of string lists with target platforms
4729
"""
48-
if not requirements:
49-
return {}
50-
51-
in_file = mrctx.path("requirements_with_markers.in.json")
52-
out_file = mrctx.path("requirements_with_markers.out.json")
53-
mrctx.file(in_file, json.encode(requirements))
54-
55-
pypi_repo_utils.execute_checked(
56-
mrctx,
57-
op = "ResolveRequirementEnvMarkers({})".format(in_file),
58-
python = pypi_repo_utils.resolve_python_interpreter(
59-
mrctx,
60-
python_interpreter = python_interpreter,
61-
python_interpreter_target = python_interpreter_target,
62-
),
63-
arguments = [
64-
"-m",
65-
"python.private.pypi.requirements_parser.resolve_target_platforms",
66-
in_file,
67-
out_file,
68-
],
69-
srcs = srcs,
70-
environment = {
71-
"PYTHONPATH": [
72-
Label("@pypi__packaging//:BUILD.bazel"),
73-
Label("//:BUILD.bazel"),
74-
],
75-
},
76-
logger = logger,
77-
)
78-
return json.decode(mrctx.read(out_file))
30+
ret = {}
31+
for req_string, platforms in requirements.items():
32+
req = _req(req_string)
33+
for platform in platforms:
34+
if evaluate(req.marker, env = env(_platform_from_str(platform, None))):
35+
ret.setdefault(req_string, []).append(platform)
36+
37+
return ret

0 commit comments

Comments
 (0)