Skip to content

Commit c5b5153

Browse files
committed
artisanal inteligence spike
1 parent 3eaf55d commit c5b5153

6 files changed

Lines changed: 147 additions & 61 deletions

File tree

python/private/pypi/extension.bzl

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ load("//python/private:auth.bzl", "AUTH_ATTRS")
2222
load("//python/private:normalize_name.bzl", "normalize_name")
2323
load("//python/private:pyproject_utils.bzl", "read_pyproject", "version_from_requires_python")
2424
load("//python/private:repo_utils.bzl", "repo_utils")
25+
load("//python/private:text_util.bzl", "render")
2526
load(":hub_builder.bzl", "hub_builder")
2627
load(":hub_repository.bzl", "hub_repository", "whl_config_settings_to_json")
2728
load(":parse_whl_name.bzl", "parse_whl_name")
@@ -464,8 +465,26 @@ You cannot use both the additive_build_content and additive_build_content_file a
464465
out = hub.build()
465466

466467
for whl_name, lib in out.whl_libraries.items():
468+
# NOTE @aignas 2026-07-04: if the same wheel is downloaded from multiple
469+
# indexes, this will fail, forcing the user to actually download the wheel
470+
# from the same and deterministic location. This is usually the case for
471+
# public wheels and users should setup the defaults.index_url to correct
472+
# fall-back in rules_python we should handle the default index to substitute
473+
# any index-url in requirements pointing to the public PyPI mirrors.
467474
if whl_name in whl_libraries:
468-
print("'{}' already in created".format(whl_name))
475+
existing = whl_libraries[whl_name]
476+
477+
# TODO @aignas 2026-07-04: stop ignoring the index_url
478+
diff = _diff_dict(existing, lib, ignore_keys = {"index_url": True})
479+
if diff:
480+
fail("'{}' already in created:\n{}".format(
481+
whl_name,
482+
"\n".join([
483+
" {}: {}".format(key, render.indent(render.dict(value)).lstrip())
484+
for key, value in diff.items()
485+
if value
486+
]),
487+
))
469488

470489
whl_libraries[whl_name] = lib
471490

@@ -1223,3 +1242,45 @@ This rule creates json files based on the whl_mods attribute.
12231242
),
12241243
},
12251244
)
1245+
1246+
# TODO dedupe code
1247+
1248+
def _diff_dict(first, second, *, ignore_keys = {}):
1249+
"""A simple utility to shallow compare dictionaries.
1250+
1251+
Args:
1252+
first: The first dictionary to compare.
1253+
second: The second dictionary to compare.
1254+
1255+
Returns:
1256+
A dictionary containing the differences, with keys "common", "different",
1257+
"extra", and "missing", or None if the dictionaries are identical.
1258+
"""
1259+
missing = {}
1260+
extra = {
1261+
key: value
1262+
for key, value in second.items()
1263+
if key not in first and key not in ignore_keys
1264+
}
1265+
common = {}
1266+
different = {}
1267+
1268+
for key, value in first.items():
1269+
if key in ignore_keys:
1270+
continue
1271+
elif key not in second:
1272+
missing[key] = value
1273+
elif value == second[key]:
1274+
common[key] = value
1275+
else:
1276+
different[key] = (value, second[key])
1277+
1278+
if missing or extra or different:
1279+
return {
1280+
"common": common,
1281+
"different": different,
1282+
"extra": extra,
1283+
"missing": missing,
1284+
}
1285+
else:
1286+
return None

python/private/pypi/generate_whl_library_build_bazel.bzl

Lines changed: 46 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"""Generate the BUILD.bazel contents for a repo defined by a whl_library."""
1616

1717
load("//python/private:text_util.bzl", "render")
18+
load(":labels.bzl", "DATA_LABEL", "DIST_INFO_LABEL", "EXTRACTED_WHEEL_FILES", "PACKAGE_METADATA_LABEL")
1819

1920
# These are functions on how to render particular args, should be reused across all rendering
2021
# invocations to make things easier.
@@ -31,10 +32,11 @@ _RENDER_FNS = {
3132
"srcs_exclude": render.list,
3233
"tags": render.list,
3334
}
35+
3436
def _render(**kwargs):
3537
return {
3638
arg: _RENDER_FNS.get(arg, repr)(value)
37-
for arg, value in kwargs.items
39+
for arg, value in kwargs.items()
3840
}
3941

4042
# NOTE @aignas 2024-10-25: We have to keep this so that files in
@@ -50,11 +52,26 @@ package(default_visibility = ["//visibility:public"])
5052

5153
def generate_whl_library_build_bazel(
5254
*,
53-
# TODO @aignas 2026-07-04: add extra args that are used in this function
55+
name,
5456
annotation = None,
5557
config_load,
58+
copy_executables = {},
59+
copy_files = {},
60+
data_exclude = [],
61+
dep_template,
62+
enable_implicit_namespace_pkgs = False,
63+
entry_points = {},
64+
extras = [],
65+
group_deps = [],
66+
group_name = None,
67+
metadata_name,
68+
metadata_version,
69+
namespace_package_files = {},
5670
purl = None,
5771
requires_dist = [],
72+
sdist_filename = None,
73+
srcs_exclude = [],
74+
visibility = ["//visibility:public"],
5875
**kwargs):
5976
"""Generate a BUILD file for an unzipped Wheel
6077
@@ -72,7 +89,7 @@ def generate_whl_library_build_bazel(
7289

7390
loads = [
7491
"""load("@package_metadata//rules:package_metadata.bzl", "package_metadata")""",
75-
"""load("@rules_python//python/private/pypi:whl_library_targets.bzl", "whl_library_srcs", "whl_library_from_requires_dist")"""
92+
"""load("@rules_python//python/private/pypi:whl_library_targets.bzl", "whl_library_srcs", "whl_library_from_requires_dist")""",
7693
]
7794

7895
srcs_kwargs = dict(
@@ -90,13 +107,11 @@ def generate_whl_library_build_bazel(
90107
copy_files = copy_files,
91108
copy_executables = copy_executables,
92109
namespace_package_files = namespace_package_files,
93-
data = [],
94110
visibility = visibility,
95111
)
96112
from_requires_kwargs = dict(
97-
name = name,
98-
metadata_name = metadata_name,
99-
metadata_version = metadata_version,
113+
name = metadata_name,
114+
version = metadata_version,
100115
requires_dist = requires_dist,
101116
extras = extras,
102117
group_deps = group_deps,
@@ -121,15 +136,15 @@ def generate_whl_library_build_bazel(
121136
render.call(
122137
"package_metadata",
123138
**_render(
124-
name = "package_metadata",
139+
name = PACKAGE_METADATA_LABEL,
125140
purl = purl,
126141
visibility = ["//:__subpackages__"],
127-
),
142+
)
128143
),
129144
render.call(
130145
"whl_library_srcs",
131146
**_render(**srcs_kwargs)
132-
)
147+
),
133148
]
134149

135150
if config_load:
@@ -138,7 +153,7 @@ def generate_whl_library_build_bazel(
138153

139154
macro_parts.append(render.call(
140155
"whl_library_from_requires_dist",
141-
**_render(**from_requires_kwargs),
156+
**_render(**from_requires_kwargs)
142157
))
143158

144159
contents = "\n".join(
@@ -155,7 +170,15 @@ def generate_whl_library_build_bazel(
155170

156171
def generate_whl_library_deps_build_bazel(
157172
*,
158-
# TODO @aignas 2026-07-04: add extra args that are used in this function
173+
name,
174+
version,
175+
config_load,
176+
dep_template,
177+
extras,
178+
group_deps,
179+
group_name,
180+
requires_dist,
181+
whl_library,
159182
**kwargs):
160183
"""Generate a BUILD file for an unzipped Wheel
161184
@@ -165,32 +188,32 @@ def generate_whl_library_deps_build_bazel(
165188
"""
166189

167190
loads = [
168-
"""load("@rules_python//python/private/pypi:whl_library_targets.bzl", "whl_library_from_requires_dist")"""
191+
"""load("@rules_python//python/private/pypi:whl_library_targets.bzl", "whl_library_from_requires_dist")""",
169192
]
170193

171194
from_requires_kwargs = dict(
172195
name = name,
173-
metadata_name = metadata_name,
174-
metadata_version = metadata_version,
196+
version = version,
175197
requires_dist = requires_dist,
176198
extras = extras,
177199
group_deps = group_deps,
178200
dep_template = dep_template,
179201
group_name = group_name,
202+
src_pkg = str(whl_library),
180203
)
181204

182205
macro_parts = [
183206
render.call(
184207
"alias",
185-
name=target,
186-
actual=whl_library.same_package_label(target),
208+
**_render(
209+
name = target,
210+
actual = str(whl_library.same_package_label(target)),
211+
)
187212
)
188213
for target in [
189-
# TODO @aignas 2026-07-04: use ./labels.bzl for the following
190-
"package_metadata",
191-
"data",
192-
"dist_info",
193-
"extracted_whl_files",
214+
DATA_LABEL,
215+
DIST_INFO_LABEL,
216+
EXTRACTED_WHEEL_FILES,
194217
]
195218
]
196219

@@ -200,7 +223,7 @@ def generate_whl_library_deps_build_bazel(
200223

201224
macro_parts.append(render.call(
202225
"whl_library_from_requires_dist",
203-
**_render(**from_requires_kwargs),
226+
**_render(**from_requires_kwargs)
204227
))
205228

206229
contents = _TEMPLATE.format(

python/private/pypi/hub_builder.bzl

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ def _add_whl_library(self, *, python_version, whl, repo):
316316
# are more platforms defined than there are wheels for and users
317317
# disallow building from sdist.
318318
return
319-
319+
320320
forbidden_args = {
321321
"annotation": True,
322322
"extra_pip_args": True,
@@ -332,13 +332,14 @@ def _add_whl_library(self, *, python_version, whl, repo):
332332
deps_args = repo.args
333333
else:
334334
whl_repo_name = "whl_{}".format(repo.whl_repo_name)
335-
336-
self._whl_libraries[whl_repo_name] = {
337-
k: v for k, v in repo.args.items()
335+
_add_library(self, repos_dict = self._whl_libraries, name = whl_repo_name, args = {
336+
k: v
337+
for k, v in repo.args.items()
338338
if k not in forbidden_args | {
339-
"config_load": True
339+
"config_load": None,
340+
"dep_template": None,
340341
}
341-
}
342+
})
342343

343344
args = repo.args
344345

@@ -351,21 +352,7 @@ def _add_whl_library(self, *, python_version, whl, repo):
351352
repos_dict = self._whl_library_deps
352353

353354
repo_name = "{}_{}_{}".format(self.name, version_label(python_version), repo.repo_name)
354-
if repo_name in repos_dict:
355-
diff = _diff_dict(repos_dict[repo_name], deps_args)
356-
if diff:
357-
self._logger.fail(lambda: (
358-
"Attempting to create a duplicate library {repo_name} for {whl_name} with different arguments. Already existing declaration has:\n".format(
359-
repo_name = repo_name,
360-
whl_name = whl.name,
361-
) + "\n".join([
362-
" {}: {}".format(key, render.indent(render.dict(value)).lstrip())
363-
for key, value in diff.items()
364-
if value
365-
])
366-
))
367-
return
368-
repos_dict[repo_name] = deps_args
355+
_add_library(self, repos_dict = repos_dict, name = repo_name, args = deps_args)
369356

370357
mapping = self._whl_map.setdefault(whl.name, {})
371358
if repo.config_setting in mapping and mapping[repo.config_setting] != repo_name:
@@ -381,6 +368,22 @@ def _add_whl_library(self, *, python_version, whl, repo):
381368

382369
### end of setters, below we have various functions to implement the public methods
383370

371+
def _add_library(self, *, repos_dict, name, args):
372+
if name in repos_dict:
373+
diff = _diff_dict(repos_dict[name], args)
374+
if diff:
375+
self._logger.fail(lambda: (
376+
"Attempting to create a duplicate library {name} with different arguments. Already existing declaration has:\n".format(
377+
repo_name = name,
378+
) + "\n".join([
379+
" {}: {}".format(key, render.indent(render.dict(value)).lstrip())
380+
for key, value in diff.items()
381+
if value
382+
])
383+
))
384+
return
385+
repos_dict[name] = args
386+
384387
def _set_get_index_urls(self, mctx, pip_attr):
385388
# Resolve the index URL through envsubst so the ``$VAR`` / ``${VAR:-default}``
386389
# form is honored when deciding whether the experimental index-url mode is

python/private/pypi/labels.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ PY_LIBRARY_PUBLIC_LABEL = "pkg"
2121
PY_LIBRARY_IMPL_LABEL = "_pkg"
2222
DATA_LABEL = "data"
2323
DIST_INFO_LABEL = "dist_info"
24+
PACKAGE_METADATA_LABEL = "package_metadata"
2425
NODEPS_LABEL = "no_deps"
2526
NODEPS_WHL_FILE_LABEL = "_whl_file"
2627
NODEPS_PY_LIBRARY_LABEL = "_srcs"

python/private/pypi/whl_library.bzl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -637,15 +637,15 @@ def _whl_library_deps_impl(rctx):
637637
return
638638

639639
build_file_contents = generate_whl_library_deps_build_bazel(
640-
dep_template = rctx.attr.dep_template,
640+
name = metadata.name,
641+
version = metadata.version,
641642
config_load = rctx.attr.config_load,
642-
metadata_name = metadata.name,
643-
metadata_version = metadata.version,
644-
requires_dist = metadata.requires_dist,
643+
dep_template = rctx.attr.dep_template,
644+
extras = rctx.attr.extras,
645645
group_deps = rctx.attr.group_deps,
646646
group_name = rctx.attr.group_name,
647-
extras = requirement(rctx.attr.requirement).extras,
648-
whl_library=rctx.attr.whl_library,
647+
requires_dist = metadata.requires_dist,
648+
whl_library = rctx.attr.whl_library,
649649
)
650650

651651
rctx.file("WORKSPACE")

0 commit comments

Comments
 (0)