Skip to content

Commit 714b245

Browse files
committed
add a test for topological ordering preference
1 parent d59f85a commit 714b245

File tree

6 files changed

+30
-14
lines changed

6 files changed

+30
-14
lines changed

python/private/py_executable.bzl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -680,17 +680,17 @@ def _create_venv_symlinks(ctx, venv_dir_map):
680680
return venv_files
681681

682682
def _build_link_map(entries):
683-
# dict[str kind, dict[str rel_path, str link_to_path]]
683+
# dict[str kind, dict[str key or rel_path, tuple[str rel_path, str link_to_path]]]
684684
link_map = {}
685685
for entry in entries:
686686
kind = entry.kind
687687
kind_map = link_map.setdefault(kind, {})
688-
if entry.venv_path in kind_map:
689-
# We ignore duplicates by design. The dependency closer to the
690-
# binary gets precedence due to the topological ordering.
691-
continue
692-
else:
693-
kind_map[entry.venv_path] = entry.link_to_path
688+
689+
# We overwrite duplicates by design. The dependency closer to the
690+
# binary gets precedence due to the topological ordering.
691+
#
692+
# This allows us to store only one version of the dist-info that is needed
693+
kind_map[entry.key or entry.venv_path] = (entry.venv_path, entry.link_to_path)
694694

695695
# An empty link_to value means to not create the site package symlink.
696696
# Because of the topological ordering, this allows binaries to remove
@@ -710,7 +710,7 @@ def _build_link_map(entries):
710710
for _ in range(len(kind_map)):
711711
if not kind_map:
712712
break
713-
dirname, value = kind_map.popitem()
713+
_, (dirname, value) = kind_map.popitem()
714714
keep_kind_map[dirname] = value
715715
prefix = dirname + "/" # Add slash to prevent /X matching /XY
716716
for maybe_suffix in kind_map.keys():

python/private/py_info.bzl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ def _VenvSymlinkKind_typedef():
4545
VenvSymlinkKind = struct(
4646
TYPEDEF = _VenvSymlinkKind_typedef,
4747
BIN = "BIN",
48-
DISTINFO = "DISTINFO",
4948
LIB = "LIB",
5049
INCLUDE = "INCLUDE",
5150
)
@@ -57,6 +56,11 @@ VenvSymlinkEntry = provider(
5756
An entry in `PyInfo.venv_symlinks`
5857
""",
5958
fields = {
59+
"key": """
60+
:type: str | None
61+
62+
Represents the value that gets used to key entries so that each package is represented only once.
63+
""",
6064
"kind": """
6165
:type: str
6266

python/private/py_library.bzl

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ load(
4141
"runfiles_root_path",
4242
)
4343
load(":flags.bzl", "AddSrcsToRunfilesFlag", "PrecompileFlag", "VenvsSitePackages")
44+
load(":normalize_name.bzl", "normalize_name")
4445
load(":precompile.bzl", "maybe_precompile")
4546
load(":py_cc_link_params_info.bzl", "PyCcLinkParamsInfo")
4647
load(":py_info.bzl", "PyInfo", "VenvSymlinkEntry", "VenvSymlinkKind")
@@ -270,20 +271,21 @@ def _get_venv_symlinks(ctx, dist_info_metadata):
270271
repo_runfiles_dirname = None
271272
dirs_with_init = {} # dirname -> runfile path
272273
venv_symlinks = []
274+
package = ""
273275
if dist_info_metadata:
274276
# in order to be able to have replacements in the venv, we have to add a
275277
# third value into the venv_symlinks, which would be the normalized
276278
# package name. This allows us to ensure that we can replace the `dist-info`
277279
# directories by checking if the package key is there.
278280
dist_info_dir = paths.basename(dist_info_metadata.dirname)
279-
#TODO remove
280-
#package, _, _suffix = dist_info_dir.rpartition(".dist-info")
281-
#package, _, _version = package.rpartition("-")
282-
#symlink_key = "{}.dist-info".format(normalize_name(package))
281+
package, _, _suffix = dist_info_dir.rpartition(".dist-info")
282+
package, _, _version = package.rpartition("-")
283+
package = normalize_name(package)
283284

284285
repo_runfiles_dirname = runfiles_root_path(ctx, dist_info_metadata.short_path).partition("/")[0]
285286
venv_symlinks.append(VenvSymlinkEntry(
286-
kind = VenvSymlinkKind.DISTINFO,
287+
key = "{}.dist-info".format(package),
288+
kind = VenvSymlinkKind.LIB,
287289
link_to_path = paths.join(repo_runfiles_dirname, site_packages_root, dist_info_dir),
288290
venv_path = dist_info_dir,
289291
))
@@ -306,6 +308,7 @@ def _get_venv_symlinks(ctx, dist_info_metadata):
306308
# This would be files that do not have directories and we just need to add
307309
# direct symlinks to them as is:
308310
venv_symlinks.append(VenvSymlinkEntry(
311+
key = None,
309312
kind = VenvSymlinkKind.LIB,
310313
link_to_path = paths.join(repo_runfiles_dirname, site_packages_root, filename),
311314
venv_path = filename,
@@ -327,6 +330,7 @@ def _get_venv_symlinks(ctx, dist_info_metadata):
327330

328331
for dirname in first_level_explicit_packages:
329332
venv_symlinks.append(VenvSymlinkEntry(
333+
key = None,
330334
kind = VenvSymlinkKind.LIB,
331335
link_to_path = paths.join(repo_runfiles_dirname, site_packages_root, dirname),
332336
venv_path = dirname,
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
# Intentionally empty
2+
3+
__version__ = "1.0.0"
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
# Intentionally empty
2+
3+
__version__ = "2.0.0"

tests/venv_site_packages_libs/bin.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ def test_distinfo_is_overriden(self):
3838

3939
dist_info_dirs = [p.name for p in site_packages.glob("*.dist-info")]
4040

41+
self.assertEqual(
42+
"2.0.0",
43+
module.__version__,
44+
)
4145
self.assertEqual(
4246
["simple-2.0.0.dist-info"],
4347
dist_info_dirs,

0 commit comments

Comments
 (0)