Skip to content

Commit dd1d0ae

Browse files
committed
Sort out activating extras & URL sources
1 parent a5a7e38 commit dd1d0ae

File tree

4 files changed

+54
-25
lines changed

4 files changed

+54
-25
lines changed

pip/private/constraints/python/defs.bzl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ def supported_python(python_tag):
1010
- IronPython
1111
1212
Explicitly allows only the `py` (generic) and `cp` (CPython) interpreters.
13-
13+
1414
Args:
1515
python_tag (str): A wheel abi tag
1616

pip/private/extension.bzl

Lines changed: 51 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,14 @@ def _parse_locks(module_ctx, venv_specs):
129129
for d in package["dependencies"]:
130130
d["name"] = normalize_name(d["name"])
131131

132+
# Note that we also have to mangle the optional deps so they tie
133+
# off too. We don't mangle group names because they're
134+
# eliminated when we resolve the depgraph.
135+
if "optional-dependencies" in package:
136+
for name, group in package["optional-dependencies"].items():
137+
for d in group:
138+
d["name"] = normalize_name(d["name"])
139+
132140
# FIXME: Should validate the lockfile but for now just stash it
133141
# Validating in starlark kinda rots anyway
134142
lock_specs[lock.hub_name][lock.venv_name] = lockfile
@@ -146,8 +154,15 @@ def _collect_configurations(repository_ctx, lock_specs):
146154
for hub_name, venvs in lock_specs.items():
147155
for venv_name, lock in venvs.items():
148156
for package in lock.get("package", []):
149-
if "registry" not in package["source"]:
150-
continue
157+
# Remote package sources
158+
# - { source = { registry = "https://some.registry/..." } }
159+
# - { source = { url = "https://ton.hosting.biz/some.whl" } }
160+
# FIXME: Git URLs?
161+
# FIXME: Egg URLs?
162+
#
163+
# These seem to be used by the package itself
164+
# - { source = { editable = "." } }
165+
# - { source = { virtual = "." } }
151166

152167
for whl in package.get("wheels", []):
153168
url = whl["url"]
@@ -167,7 +182,7 @@ def _collect_configurations(repository_ctx, lock_specs):
167182
# Ignore configurations for unsupported interpreters
168183
if not supported_python(python_tag):
169184
continue
170-
185+
171186
python_tags[python_tag] = 1
172187

173188
for platform_tag in parsed_wheel.platform_tags:
@@ -208,9 +223,6 @@ def _raw_sdist_repos(module_ctx, lock_specs):
208223
for hub_name, venvs in lock_specs.items():
209224
for venv_name, lock in venvs.items():
210225
for package in lock.get("package", []):
211-
if "registry" not in package["source"]:
212-
continue
213-
214226
sdist = package.get("sdist")
215227
if sdist == None:
216228
continue
@@ -253,9 +265,6 @@ def _raw_whl_repos(module_ctx, lock_specs):
253265
for hub_name, venvs in lock_specs.items():
254266
for venv_name, lock in venvs.items():
255267
for package in lock.get("package", []):
256-
if "registry" not in package["source"]:
257-
continue
258-
259268
wheels = package.get("wheels", [])
260269
for whl in wheels:
261270
url = whl["url"]
@@ -296,9 +305,6 @@ def _sbuild_repos(module_ctx, lock_specs):
296305
for hub_name, venvs in lock_specs.items():
297306
for venv_name, lock in venvs.items():
298307
for package in lock.get("package", []):
299-
if "registry" not in package["source"]:
300-
continue
301-
302308
if "sdist" not in package:
303309
continue
304310

@@ -322,9 +328,6 @@ def _whl_install_repos(module_ctx, lock_specs):
322328
for hub_name, venvs in lock_specs.items():
323329
for venv_name, lock in venvs.items():
324330
for package in lock.get("package", []):
325-
if "registry" not in package["source"]:
326-
continue
327-
328331
# This is where we need to actually choose which wheel we will
329332
# "install", and so this is where prebuild selection needs to
330333
# happen according to constraints.
@@ -353,32 +356,57 @@ def _venv_hub_name(hub, venv):
353356
def _group_repos(module_ctx, lock_specs):
354357
# Hub -> requirement -> venv -> True
355358
# For building hubs we need to know what venv configurations a given
359+
360+
# TODO: Missing support for `marker=""` specifications in `dependencies`.
361+
# Deps may be conditional on this or that predicate being satisfied.
362+
# Dependencies which have markers need to be rewritten so that the
363+
# dependency edge goes through a select.
364+
#
365+
# TODO: What happens if you have a cycle only when this or that feature is
366+
# active? Probably the fix is to turn on all dependency edges
367+
356368
package_venvs = {}
357369

358370
for hub_name, venvs in lock_specs.items():
359371
package_venvs[hub_name] = {}
360372

361373
for venv_name, lock in venvs.items():
362-
# First we need to build the adjacency graph
374+
# Index all the packages by name so activating extras is easy
375+
packages = {
376+
package["name"]: package
377+
for package in lock.get("package", [])
378+
}
379+
380+
# Build a graph {name: {dependency_name: dependency_marker_condition}}
363381
graph = {}
364382

365-
for package in lock.get("package", []):
383+
for name, package in packages.items():
366384
if "registry" not in package["source"]:
367385
continue
368386

369-
deps = []
387+
deps = {}
370388

371389
# Enter the package into the venv internal graph
372-
graph[package["name"]] = deps
390+
graph.setdefault(package["name"], {})
391+
373392
for d in package.get("dependencies", []):
374-
deps.append(d["name"])
393+
# Or in all the dep bits
394+
graph[package["name"]][d["name"]] = d.get("marker", "")
395+
396+
# Activate extras
397+
extras = packages[d["name"]].get("optional-dependencies", {})
398+
for extra in d.get("extra", []):
399+
for extra_dep in extras.get(extra, []):
400+
graph.setdefault(d["name"], {})
401+
graph[d["name"]][extra_dep["name"]] = extra_dep.get("marker", "")
375402

376403
# Enter the package into the venv hub manifest
377404
package_venvs[hub_name].setdefault(package["name"], {})
378405
package_venvs[hub_name][package["name"]][venv_name] = 1
379406

380407
# So we can find sccs/clusters which need to co-occur
381-
cycle_groups = sccs(graph)
408+
# Note that we're assuming ALL marker conditional deps are live.
409+
cycle_groups = sccs({k: v.keys() for k, v in graph.items()})
382410

383411
# Now we can assign names to the sccs and collect deps Note that
384412
# _every_ node in the graph will be in _a_ scc, those sccs are just
@@ -412,11 +440,12 @@ def _group_repos(module_ctx, lock_specs):
412440
if d not in scc:
413441
deps[name][d] = 1
414442

443+
# TODO: How do we plumb markers through here?
444+
415445
# At this point we have mapped every package to an scc (possibly of
416446
# size 1) which it participates in, named those sccs, and identified
417447
# their direct dependencies beyond the scc. So we can just lay down
418448
# targets.
419-
420449
venv_hub(
421450
name = _venv_hub_name(hub_name, venv_name),
422451
aliases = scc_aliases, # String dict

pip/private/tomltool/toml.bzl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def _translate_libc(repository_ctx):
4646
ldd = repository_ctx.execute(["ldd", "--version"]).stdout.lower()
4747
if "gnu" in ldd or "glibc" in ldd:
4848
return "gnu"
49-
49+
5050
elif "musl" in ldd:
5151
return "musl"
5252

pip/private/whl_install/repository.bzl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ def _whl_install_impl(repository_ctx):
7979
# Escape hatch for ignoring unsupported interpreters
8080
if not supported_python(python_tag):
8181
continue
82-
82+
8383
for platform_tag in parsed.platform_tags:
8484
# Escape hatch for ignoring weird unsupported platforms
8585
if not supported_platform(platform_tag):

0 commit comments

Comments
 (0)