|
1 |
| -from typing import Optional |
| 1 | +from typing import List, Optional |
2 | 2 |
|
3 | 3 | from pip._internal.models.direct_url import ArchiveInfo, DirectUrl, DirInfo, VcsInfo
|
4 |
| -from pip._internal.models.link import Link |
| 4 | +from pip._internal.models.link import Link, links_equivalent |
5 | 5 | from pip._internal.utils.urls import path_to_url
|
6 | 6 | from pip._internal.vcs import vcs
|
7 | 7 |
|
@@ -85,3 +85,42 @@ def direct_url_from_link(
|
85 | 85 | info=ArchiveInfo(hash=hash),
|
86 | 86 | subdirectory=link.subdirectory_fragment,
|
87 | 87 | )
|
| 88 | + |
| 89 | + |
| 90 | +def _link_from_direct_url(direct_url: DirectUrl) -> Link: |
| 91 | + """Create a link from given direct URL construct. |
| 92 | +
|
| 93 | + This function is designed specifically for ``link_matches_direct_url``, and |
| 94 | + does NOT losslessly reconstruct the original link that produced the |
| 95 | + DirectUrl. Namely: |
| 96 | +
|
| 97 | + * The auth part is ignored (since it does not affect link equivalency). |
| 98 | + * Only "subdirectory" and hash fragment parts are considered, and the |
| 99 | + ordering of the kept parts are not considered (since only their values |
| 100 | + affect link equivalency). |
| 101 | +
|
| 102 | + .. seealso:: ``pip._internal.models.link.links_equivalent()`` |
| 103 | + """ |
| 104 | + url = direct_url.url |
| 105 | + hash_frag = "" |
| 106 | + |
| 107 | + direct_url_info = direct_url.info |
| 108 | + if isinstance(direct_url_info, VcsInfo): |
| 109 | + url = f"{url}@{direct_url_info.requested_revision}" |
| 110 | + elif isinstance(direct_url_info, ArchiveInfo): |
| 111 | + hash_frag = direct_url_info.hash |
| 112 | + |
| 113 | + fragment_parts: List[str] = [] |
| 114 | + if direct_url.subdirectory is not None: |
| 115 | + fragment_parts.append(f"subdirectory={direct_url.subdirectory}") |
| 116 | + if hash_frag: |
| 117 | + fragment_parts.append(hash_frag) |
| 118 | + if fragment_parts: |
| 119 | + fragment = "&".join(fragment_parts) |
| 120 | + url = f"{url}#{fragment}" |
| 121 | + |
| 122 | + return Link(url) |
| 123 | + |
| 124 | + |
| 125 | +def link_matches_direct_url(link: Link, direct_url: DirectUrl) -> bool: |
| 126 | + return links_equivalent(link, _link_from_direct_url(direct_url)) |
0 commit comments