1 from typing import Optional
3 from pip._internal.models.direct_url import ArchiveInfo, DirectUrl, DirInfo, VcsInfo
4 from pip._internal.models.link import Link
5 from pip._internal.utils.urls import path_to_url
6 from pip._internal.vcs import vcs
9 def direct_url_as_pep440_direct_reference(direct_url: DirectUrl, name: str) -> str:
10 """Convert a DirectUrl to a pip requirement string."""
11 direct_url.validate() # if invalid, this is a pip bug
12 requirement = name + " @ "
14 if isinstance(direct_url.info, VcsInfo):
15 requirement += "{}+{}@{}".format(
16 direct_url.info.vcs, direct_url.url, direct_url.info.commit_id
18 elif isinstance(direct_url.info, ArchiveInfo):
19 requirement += direct_url.url
20 if direct_url.info.hash:
21 fragments.append(direct_url.info.hash)
23 assert isinstance(direct_url.info, DirInfo)
24 requirement += direct_url.url
25 if direct_url.subdirectory:
26 fragments.append("subdirectory=" + direct_url.subdirectory)
28 requirement += "#" + "&".join(fragments)
32 def direct_url_for_editable(source_dir: str) -> DirectUrl:
34 url=path_to_url(source_dir),
35 info=DirInfo(editable=True),
39 def direct_url_from_link(
40 link: Link, source_dir: Optional[str] = None, link_is_in_wheel_cache: bool = False
43 vcs_backend = vcs.get_backend_for_scheme(link.scheme)
45 url, requested_revision, _ = vcs_backend.get_url_rev_and_auth(
46 link.url_without_fragment
48 # For VCS links, we need to find out and add commit_id.
49 if link_is_in_wheel_cache:
50 # If the requested VCS link corresponds to a cached
51 # wheel, it means the requested revision was an
52 # immutable commit hash, otherwise it would not have
53 # been cached. In that case we don't have a source_dir
54 # with the VCS checkout.
55 assert requested_revision
56 commit_id = requested_revision
58 # If the wheel was not in cache, it means we have
59 # had to checkout from VCS to build and we have a source_dir
60 # which we can inspect to find out the commit id.
62 commit_id = vcs_backend.get_revision(source_dir)
68 requested_revision=requested_revision,
70 subdirectory=link.subdirectory_fragment,
72 elif link.is_existing_dir():
74 url=link.url_without_fragment,
76 subdirectory=link.subdirectory_fragment,
80 hash_name = link.hash_name
82 hash = f"{hash_name}={link.hash}"
84 url=link.url_without_fragment,
85 info=ArchiveInfo(hash=hash),
86 subdirectory=link.subdirectory_fragment,