@@ -680,32 +680,30 @@ def _create_venv_symlinks(ctx, venv_dir_map):
680680 return venv_files
681681
682682def _build_link_map (entries ):
683- # dict[str kind, dict[str rel_path, str link_to_path]]
684- link_map = {}
683+ # dict[str package, dict[str kind, dict[str rel_path, str link_to_path] ]]
684+ pkg_link_map = {}
685685
686- # Here we store venv paths by package
687- # dict[str package, dict[str kind, list[str venv_path]]]
688- pkg_map = {}
686+ # dict[str package, str version]
687+ version_by_pkg = {}
689688
690689 for entry in entries :
691- kind = entry .kind
692- kind_map = link_map .setdefault (kind , {})
693-
694- # TODO @aignas 2025-05-31: explain where we use the version
695- package = None
690+ package = ""
696691 if entry .package :
697- package , _ , _version = entry .package .partition ("-" )
692+ # We have normalized the version/package to PEP440 spec
693+ package , _ , version = entry .package .partition ("-" )
694+
695+ if version_by_pkg .get (package ) != version :
696+ # If we detect that we are adding a different package version, clear the
697+ # previously added values.
698+ version_by_pkg [package ] = version
698699
699- # If we detect that we are adding a dist-info for an already existing package
700- # we need to pop all of the previous symlinks from the link_map
701- if entry .venv_path .endswith (".dist-info" ) and package in pkg_map :
702- # dist-info will come always first
703- for kind , dir_paths in pkg_map .pop (package ).items ():
704- for dir_path in dir_paths :
705- link_map [kind ].pop (dir_path )
700+ # Ensure that we start fresh
701+ pkg_link_map .pop (package , None )
706702
707- pkg_venv_paths = pkg_map .setdefault (package , {}).setdefault (entry .kind , [])
708- pkg_venv_paths .append (entry .venv_path )
703+ link_map = pkg_link_map .setdefault (package , {})
704+
705+ kind = entry .kind
706+ kind_map = link_map .setdefault (kind , {})
709707
710708 # We overwrite duplicates by design. The dependency closer to the
711709 # binary gets precedence due to the topological ordering.
@@ -716,28 +714,30 @@ def _build_link_map(entries):
716714 # An empty link_to value means to not create the site package symlink.
717715 # Because of the topological ordering, this allows binaries to remove
718716 # entries by having an earlier dependency produce empty link_to values.
719- for kind , kind_map in link_map .items ():
720- for dir_path , link_to in kind_map .items ():
721- if not link_to :
722- kind_map .pop (dir_path )
717+ for link_map in pkg_link_map .values ():
718+ for kind , kind_map in link_map .items ():
719+ for dir_path , link_to in kind_map .items ():
720+ if not link_to :
721+ kind_map .pop (dir_path )
723722
724723 # dict[str kind, dict[str rel_path, str link_to_path]]
725724 keep_link_map = {}
726725
727726 # Remove entries that would be a child path of a created symlink.
728727 # Earlier entries have precedence to match how exact matches are handled.
729- for kind , kind_map in link_map .items ():
730- keep_kind_map = keep_link_map .setdefault (kind , {})
731- for _ in range (len (kind_map )):
732- if not kind_map :
733- break
734- dirname , value = kind_map .popitem ()
735- keep_kind_map [dirname ] = value
736- prefix = dirname + "/" # Add slash to prevent /X matching /XY
737- for maybe_suffix in kind_map .keys ():
738- maybe_suffix += "/" # Add slash to prevent /X matching /XY
739- if maybe_suffix .startswith (prefix ) or prefix .startswith (maybe_suffix ):
740- kind_map .pop (maybe_suffix )
728+ for link_map in pkg_link_map .values ():
729+ for kind , kind_map in link_map .items ():
730+ keep_kind_map = keep_link_map .setdefault (kind , {})
731+ for _ in range (len (kind_map )):
732+ if not kind_map :
733+ break
734+ dirname , value = kind_map .popitem ()
735+ keep_kind_map [dirname ] = value
736+ prefix = dirname + "/" # Add slash to prevent /X matching /XY
737+ for maybe_suffix in kind_map .keys ():
738+ maybe_suffix += "/" # Add slash to prevent /X matching /XY
739+ if maybe_suffix .startswith (prefix ) or prefix .startswith (maybe_suffix ):
740+ kind_map .pop (maybe_suffix )
741741 return keep_link_map
742742
743743def _map_each_identity (v ):
0 commit comments