Skip to content
Merged
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
4 changes: 4 additions & 0 deletions .bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
# To update the file, execute
import %workspace%/.bazelrc.deleted_packages

# Symlinks are used extensively because of runfiles, venvs, and other reasons.
# Supporting otherwise is very complex with little benefit.
startup --windows_enable_symlinks

test --test_output=errors

# Do NOT implicitly create empty __init__.py files in the runfiles tree.
Expand Down
12 changes: 11 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ END_UNRELEASED_TEMPLATE

{#v0-0-0-changed}
### Changed

**Breaking**
* {obj}`--windows_enable_symlinks` is required. Add `startup
--windows_enable_symlinks` to your `.bazelrc` to enable Bazel using full
symlink support on Windows.

Other changes:
* (pypi) Update dependencies used for `compile_pip_requirements`, building
sdists in the `whl_library` rule and fetching wheels using `pip`.

Expand All @@ -70,7 +77,10 @@ END_UNRELEASED_TEMPLATE

{#v0-0-0-added}
### Added
* Nothing added.
* (pypi) Write SimpleAPI contents to the `MODULE.bazel.lock` file if using
{obj}`experimental_index_url` which should speed up consecutive initializations and should no
longer require the network access if the cache is hydrated.
Implements [#2731](https://github.com/bazel-contrib/rules_python/issues/2731).

{#v1-9-0}
## [1.9.0] - 2026-02-21
Expand Down
3 changes: 3 additions & 0 deletions python/private/pypi/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,9 @@ bzl_library(
bzl_library(
name = "pypi_cache_bzl",
srcs = ["pypi_cache.bzl"],
deps = [
":version_from_filename_bzl",
],
)

bzl_library(
Expand Down
21 changes: 16 additions & 5 deletions python/private/pypi/extension.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ You cannot use both the additive_build_content and additive_build_content_file a
# dict[str repo, HubBuilder]
# See `hub_builder.bzl%hub_builder()` for `HubBuilder`
pip_hub_map = {}
simpleapi_cache = pypi_cache()
simpleapi_cache = pypi_cache(mctx = module_ctx)

for mod in module_ctx.modules:
for pip_attr in mod.tags.parse:
Expand Down Expand Up @@ -293,6 +293,7 @@ You cannot use both the additive_build_content and additive_build_content_file a
config = config,
exposed_packages = exposed_packages,
extra_aliases = extra_aliases,
facts = simpleapi_cache.get_facts(),
hub_group_map = hub_group_map,
hub_whl_map = hub_whl_map,
whl_libraries = whl_libraries,
Expand Down Expand Up @@ -372,7 +373,11 @@ def _pip_impl(module_ctx):
module_ctx: module contents
"""

mods = parse_modules(module_ctx, enable_pipstar = rp_config.enable_pipstar, enable_pipstar_extract = rp_config.enable_pipstar and rp_config.bazel_8_or_later)
mods = parse_modules(
module_ctx,
enable_pipstar = rp_config.enable_pipstar,
enable_pipstar_extract = rp_config.enable_pipstar and rp_config.bazel_8_or_later,
)

# Build all of the wheel modifications if the tag class is called.
_whl_mods_impl(mods.whl_mods)
Expand All @@ -394,9 +399,15 @@ def _pip_impl(module_ctx):
groups = mods.hub_group_map.get(hub_name),
)

return module_ctx.extension_metadata(
reproducible = True,
)
# The code is smart to not return facts if we don't support the mechanism for that.
# Hence we should not pass it to the metadata
if mods.facts:
return module_ctx.extension_metadata(
reproducible = True,
facts = mods.facts,
)
else:
return module_ctx.extension_metadata(reproducible = True)

_default_attrs = {
"arch_name": attr.string(
Expand Down
8 changes: 4 additions & 4 deletions python/private/pypi/hub_builder.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -395,11 +395,11 @@ def _set_get_index_urls(self, pip_attr):
index_url = pip_attr.experimental_index_url,
extra_index_urls = pip_attr.experimental_extra_index_urls or [],
index_url_overrides = pip_attr.experimental_index_url_overrides or {},
sources = [
d
for d in distributions
sources = {
d: versions
for d, versions in distributions.items()
if _use_downloader(self, python_version, d)
],
},
envsubst = pip_attr.envsubst,
# Auth related info
netrc = pip_attr.netrc,
Expand Down
28 changes: 15 additions & 13 deletions python/private/pypi/parse_requirements.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def parse_requirements(
os, arch combinations.
extra_pip_args (string list): Extra pip arguments to perform extra validations and to
be joined with args found in files.
get_index_urls: Callable[[ctx, list[str]], dict], a callable to get all
get_index_urls: Callable[[ctx, dict[str, list[str]]], dict], a callable to get all
of the distribution URLs from a PyPI index. Accepts ctx and
distribution names to query.
evaluate_markers: A function to use to evaluate the requirements.
Expand Down Expand Up @@ -170,15 +170,17 @@ def parse_requirements(

index_urls = {}
if get_index_urls:
distributions = {}
for reqs in requirements_by_platform.values():
for req in reqs.values():
if req.srcs.url:
continue

distributions.setdefault(req.distribution, []).append(req.srcs.version)

index_urls = get_index_urls(
ctx,
# Use list({}) as a way to have a set
list({
req.distribution: None
for reqs in requirements_by_platform.values()
for req in reqs.values()
if not req.srcs.url
}),
distributions,
)

ret = []
Expand Down Expand Up @@ -267,7 +269,7 @@ def _package_srcs(
url = "",
filename = "",
sha256 = "",
yanked = False,
yanked = None,
)
req_line = r.srcs.requirement_line
else:
Expand Down Expand Up @@ -379,7 +381,7 @@ def _add_dists(*, requirement, index_urls, target_platform, logger = None):
url = requirement.srcs.url,
filename = requirement.srcs.filename,
sha256 = requirement.srcs.shas[0] if requirement.srcs.shas else "",
yanked = False,
yanked = None,
)

return dist, False
Expand All @@ -403,20 +405,20 @@ def _add_dists(*, requirement, index_urls, target_platform, logger = None):
# See https://packaging.python.org/en/latest/specifications/simple-repository-api/#adding-yank-support-to-the-simple-api

maybe_whl = index_urls.whls.get(sha256)
if maybe_whl and not maybe_whl.yanked:
if maybe_whl and maybe_whl.yanked == None:
whls.append(maybe_whl)
continue

maybe_sdist = index_urls.sdists.get(sha256)
if maybe_sdist and not maybe_sdist.yanked:
if maybe_sdist and maybe_sdist.yanked == None:
sdist = maybe_sdist
continue

logger.warn(lambda: "Could not find a whl or an sdist with sha256={}".format(sha256))

yanked = {}
for dist in whls + [sdist]:
if dist and dist.yanked:
if dist and dist.yanked != None:
yanked.setdefault(dist.yanked, []).append(dist.filename)
if yanked:
logger.warn(lambda: "\n".join([
Expand Down
Loading