Skip to content

Commit e5043a8

Browse files
authored
Merge pull request #134 from gmathiou4/Relative-links-confuse-PyPi
relative links_fix
2 parents 1831e01 + b74a7c3 commit e5043a8

18 files changed

+1413
-1269
lines changed

src/python_inspector/utils_pypi.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
from typing import List
2121
from typing import NamedTuple
2222
from urllib.parse import quote_plus
23+
from urllib.parse import urlparse
24+
from urllib.parse import urlunparse
2325

2426
import attr
2527
import packageurl
@@ -949,7 +951,6 @@ def get_sdist_name_ver_ext(filename):
949951

950952
@attr.attributes
951953
class Sdist(Distribution):
952-
953954
extension = attr.ib(
954955
repr=False,
955956
type=str,
@@ -1595,11 +1596,37 @@ def fetch_links(
15951596
url, _, _sha256 = anchor_tag["href"].partition("#sha256=")
15961597
if "data-requires-python" in anchor_tag.attrs:
15971598
python_requires = anchor_tag.attrs["data-requires-python"]
1599+
# Resolve relative URL
1600+
url = resolve_relative_url(package_url, url)
15981601
links.append(Link(url=url, python_requires=python_requires))
15991602
# TODO: keep sha256
16001603
return links
16011604

16021605

1606+
def resolve_relative_url(package_url, url):
1607+
"""
1608+
Return the resolved `url` URLstring given a `package_url` base URL string
1609+
of a package.
1610+
1611+
For example:
1612+
>>> resolve_relative_url("https://example.com/package", "../path/file.txt")
1613+
'https://example.com/path/file.txt'
1614+
"""
1615+
if not url.startswith(("http://", "https://")):
1616+
base_url_parts = urlparse(package_url)
1617+
url_parts = urlparse(url)
1618+
# If the relative URL starts with '..', remove the last directory from the base URL
1619+
if url_parts.path.startswith(".."):
1620+
path = base_url_parts.path.rstrip("/").rsplit("/", 1)[0] + url_parts.path[2:]
1621+
else:
1622+
path = urlunparse(
1623+
("", "", url_parts.path, url_parts.params, url_parts.query, url_parts.fragment)
1624+
)
1625+
resolved_url_parts = base_url_parts._replace(path=path)
1626+
url = urlunparse(resolved_url_parts)
1627+
return url
1628+
1629+
16031630
PYPI_PUBLIC_REPO = PypiSimpleRepository(index_url=PYPI_SIMPLE_URL)
16041631
DEFAULT_PYPI_REPOS = (PYPI_PUBLIC_REPO,)
16051632
DEFAULT_PYPI_REPOS_BY_URL = {r.index_url: r for r in DEFAULT_PYPI_REPOS}

tests/data/azure-devops.req-310-expected.json

Lines changed: 342 additions & 265 deletions
Large diffs are not rendered by default.

tests/data/azure-devops.req-38-expected.json

Lines changed: 342 additions & 265 deletions
Large diffs are not rendered by default.

tests/data/fetch_links_test.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<!DOCTYPE html>
2+
<html><head><title>Simple Index</title><meta name="api-version" value="2" /></head><body>
3+
<a href="../sources.whl#sha256=a4e66406acabbb0a6606c89c5e61bacd2847f5393818b90490021a3929b47807" rel="internal">sources.whl</a><br />
4+
</body></html>

tests/data/frozen-requirements.txt-expected.json

Lines changed: 21 additions & 19 deletions
Large diffs are not rendered by default.

tests/data/insecure-setup-2/setup.py-expected.json

Lines changed: 62 additions & 66 deletions
Large diffs are not rendered by default.

tests/data/pinned-pdt-requirements.txt-expected.json

Lines changed: 38 additions & 52 deletions
Large diffs are not rendered by default.

tests/data/pinned-requirements.txt-expected.json

Lines changed: 40 additions & 54 deletions
Large diffs are not rendered by default.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[
2+
[
3+
"https://pypi.org/simple/sources.whl",
4+
null
5+
]
6+
]

tests/data/single-url-except-simple-expected.json

Lines changed: 269 additions & 174 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)