Skip to content

Commit d61e9d1

Browse files
mathboumathboupre-commit-ci[bot]Mathieudomdfcoding
authored
Query objects.inv from homepage url (#40)
* ✨ query objects.inv from homepage url * 🎨 pre-commit run * 💡 fix typehints * ⚡ cache metadata * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * 🎨 add blank line after docstring * ✅ fix seeding test assertion * 🚨 make mypy happy * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * ✅ fix packaging url for test * ✅ fix numpy error check * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Minor nits --------- Co-authored-by: mathbou <m.bouzard@nki.local> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Mathieu <923463-mathbou@users.noreply.gitlab.com> Co-authored-by: Dominic Davis-Foster <dominic@davis-foster.co.uk>
1 parent 3386250 commit d61e9d1

13 files changed

+44
-38
lines changed

seed_intersphinx_mapping/__init__.py

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,10 @@
3333
# stdlib
3434
import functools
3535
import json
36+
import os.path
3637
import re
3738
from typing import Dict, Optional, Tuple, Union
39+
from urllib.parse import urlparse
3840

3941
# 3rd party
4042
import dist_meta
@@ -74,24 +76,29 @@ def _get_project_links(project_name: str) -> MetadataMapping:
7476
# Try a local package first
7577
try:
7678
dist = dist_meta.distributions.get_distribution(project_name)
77-
raw_urls = dist.get_metadata().get_all("Project-URL", default=())
79+
metadata = dist.get_metadata()
80+
raw_urls = metadata.get_all("Project-URL", default=())
7881

7982
for url in raw_urls:
80-
label, url, *_ = map(str.strip, url.split(','))
83+
label, url = map(str.strip, url.split(',', 1))
8184
if _DOCUMENTATION_RE.match(label):
8285
urls[label] = url
8386

87+
urls["Home-Page"] = metadata.get("Home-Page", '')
88+
8489
except dist_meta.distributions.DistributionNotFoundError:
8590
# Fall back to PyPI
8691

8792
with PyPIJSON() as client:
88-
metadata = client.get_metadata(project_name).info
93+
pypi_metadata = client.get_metadata(project_name).info
8994

90-
if "project_urls" in metadata and metadata["project_urls"]:
91-
for label, url in metadata["project_urls"].items():
95+
if "project_urls" in pypi_metadata and pypi_metadata["project_urls"]:
96+
for label, url in pypi_metadata["project_urls"].items():
9297
if _DOCUMENTATION_RE.match(label):
9398
urls[label] = url
9499

100+
urls["Homepage"] = pypi_metadata.get("home_page", '')
101+
95102
return urls
96103

97104

@@ -127,25 +134,27 @@ def get_sphinx_doc_url(pypi_name: str) -> str:
127134
:exc:`apeye.slumber_url.exceptions.HttpNotFoundError` if the project could not be found on PyPI.
128135
"""
129136

130-
for key, value in _get_project_links(pypi_name).items():
137+
docs_urls = []
138+
for value in _get_project_links(pypi_name).values():
139+
if not value:
140+
continue
131141

132142
# Follow redirects to get actual URL
133143
r = requests.head(value, allow_redirects=True, timeout=10)
134-
if r.status_code != 200: # pragma: no cover
135-
raise ValueError(f"Documentation URL not found: HTTP Status {r.status_code}.")
136144

137-
docs_url = r.url
145+
if r.status_code == 200:
146+
has_extension = os.path.splitext(urlparse(r.url).path)[-1]
147+
url = os.path.dirname(r.url) if has_extension else r.url
148+
docs_urls.append(url)
138149

139-
if docs_url.endswith('/'):
140-
objects_inv_url = f"{docs_url}objects.inv"
141-
else: # pragma: no cover
142-
objects_inv_url = f"{docs_url}/objects.inv"
150+
for docs_url in docs_urls:
151+
objects_inv_url = f"{docs_url.rstrip('/')}/objects.inv"
143152

144153
r = requests.head(objects_inv_url, allow_redirects=True, timeout=10)
145154
if r.status_code != 200:
146-
raise ValueError(f"objects.inv not found at url {objects_inv_url}: HTTP Status {r.status_code}.")
147-
148-
return docs_url
155+
stderr_writer(f"WARNING: objects.inv not found at url {objects_inv_url}: HTTP Status {r.status_code}.")
156+
else:
157+
return docs_url
149158

150159
raise ValueError("Documentation URL not found in data from PyPI.")
151160

seed_intersphinx_mapping/fallback_mapping.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
"scikit-learn": "https://scikit-learn.org/stable/",
3131
"six": "https://six.readthedocs.io/",
3232
"slumber": "https://slumber.readthedocs.io/en/v0.6.0/",
33-
"sphinx": "https://www.sphinx-doc.org/en/3.x/",
33+
"sphinx": "https://www.sphinx-doc.org/en/master/",
3434
"typing": "https://docs.python.org/3/",
3535
"typing-extensions": "https://typing-extensions.readthedocs.io/en/latest/",
3636
"typing_extensions": "https://typing-extensions.readthedocs.io/en/latest/",

tests/test_core.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def test_get_sphinx_doc_url():
2424
with pytest.raises(ValueError, match="Documentation URL not found in data from PyPI."):
2525
get_sphinx_doc_url("slumber")
2626

27-
with pytest.raises(ValueError, match="objects.inv not found at url .*: HTTP Status 404"):
27+
with pytest.raises(ValueError, match="Documentation URL not found in data from PyPI."):
2828
get_sphinx_doc_url("autodoc_pydantic")
2929

3030
assert cache.clear(get_sphinx_doc_url)
@@ -35,10 +35,7 @@ def test_get_sphinx_doc_url():
3535

3636
if sys.version_info[:2] != (3, 8):
3737
# Latest numpy's "Documentation" url doesn't point to Sphinx docs.
38-
with pytest.raises(
39-
ValueError,
40-
match="objects.inv not found at url https://numpy.org/doc/objects.inv: HTTP Status 404."
41-
):
38+
with pytest.raises(ValueError, match="Documentation URL not found in data from PyPI."):
4239
get_sphinx_doc_url("numpy")
4340
else:
4441
assert re.match(r"https://numpy\.org/doc/1\.\d\d/", get_sphinx_doc_url("numpy"))

tests/test_seeding.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@
2525
"packaging": ("https://packaging.pypa.io/en/stable/", None),
2626
"requests": ("https://requests.readthedocs.io/en/latest/", None),
2727
"slumber": ("https://slumber.readthedocs.io/en/v0.6.0/", None),
28-
"sphinx": ("https://www.sphinx-doc.org/en/3.x/", None),
28+
"sphinx": ("https://www.sphinx-doc.org/en/master/", None),
2929
}
3030
bad_expected_mapping = {
3131
"domdf-python-tools": ("https://domdf-python-tools.readthedocs.io/en/latest/", None),
3232
"packaging": ("https://packaging.pypa.io/en/stable/", None),
33-
"sphinx": ("https://www.sphinx-doc.org/en/3.x/", None),
33+
"sphinx": ("https://www.sphinx-doc.org/en/master/", None),
3434
}
3535

3636

@@ -50,12 +50,12 @@ def test_seed_intersphinx_mapping(
5050

5151
assert seed_intersphinx_mapping(*parse_requirements_txt(tmp_pathplus)) == expects
5252
err = capsys.readouterr().err
53-
assert err == "WARNING: Unable to determine documentation url for project sphinxcontrib-domaintools\n"
53+
assert "WARNING: Unable to determine documentation url for project sphinxcontrib-domaintools\n" in err
5454

5555
requirements, comments, invalid = read_requirements(tmp_pathplus / "requirements.txt", include_invalid=True)
5656
assert seed_intersphinx_mapping(*requirements) == expects
5757
err = capsys.readouterr().err
58-
assert err == "WARNING: Unable to determine documentation url for project sphinxcontrib-domaintools\n"
58+
assert "WARNING: Unable to determine documentation url for project sphinxcontrib-domaintools\n" in err
5959

6060

6161
@pytest.mark.parametrize(
@@ -70,7 +70,7 @@ def test_seed_intersphinx_mapping_pyproject(tmp_pathplus: PathPlus, contents: st
7070

7171
assert seed_intersphinx_mapping(*parse_pyproject_toml(tmp_pathplus)) == expects
7272
err = capsys.readouterr().err
73-
assert err == "WARNING: Unable to determine documentation url for project sphinxcontrib-domaintools\n"
73+
assert err.endswith("WARNING: Unable to determine documentation url for project sphinxcontrib-domaintools\n")
7474

7575

7676
@pytest.mark.parametrize(
@@ -85,7 +85,7 @@ def test_seed_intersphinx_mapping_flit(tmp_pathplus: PathPlus, contents: str, ex
8585

8686
assert seed_intersphinx_mapping(*parse_flit_requirements(tmp_pathplus)) == expects
8787
err = capsys.readouterr().err
88-
assert err == "WARNING: Unable to determine documentation url for project sphinxcontrib-domaintools\n"
88+
assert err.endswith("WARNING: Unable to determine documentation url for project sphinxcontrib-domaintools\n")
8989

9090

9191
@pytest.mark.parametrize("pkg_requirements_source", ["requirements", "flit", "pyproject", "pyproject.toml"])
@@ -125,7 +125,7 @@ def test_sphinx_seed_intersphinx_mapping_mocked(
125125
advanced_data_regression.check(config.intersphinx_mapping)
126126

127127
err = capsys.readouterr().err
128-
assert err == "WARNING: Unable to determine documentation url for project sphinxcontrib-domaintools\n"
128+
assert err.endswith("WARNING: Unable to determine documentation url for project sphinxcontrib-domaintools\n")
129129

130130

131131
def test_sphinx_seed_intersphinx_mapping_list_mocked(

tests/test_seeding_/test_sphinx_seed_intersphinx_mapping_list_mocked.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@ slumber:
1616
- - null
1717
sphinx:
1818
- sphinx
19-
- - https://www.sphinx-doc.org/en/3.x/
19+
- - https://www.sphinx-doc.org/en/master/
2020
- - null

tests/test_seeding_/test_sphinx_seed_intersphinx_mapping_mocked_bad_example_requirements_flit_.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ packaging:
88
- - null
99
sphinx:
1010
- sphinx
11-
- - https://www.sphinx-doc.org/en/3.x/
11+
- - https://www.sphinx-doc.org/en/master/
1212
- - null

tests/test_seeding_/test_sphinx_seed_intersphinx_mapping_mocked_bad_example_requirements_pyproject_.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ packaging:
88
- - null
99
sphinx:
1010
- sphinx
11-
- - https://www.sphinx-doc.org/en/3.x/
11+
- - https://www.sphinx-doc.org/en/master/
1212
- - null

tests/test_seeding_/test_sphinx_seed_intersphinx_mapping_mocked_bad_example_requirements_pyproject_toml_.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ packaging:
88
- - null
99
sphinx:
1010
- sphinx
11-
- - https://www.sphinx-doc.org/en/3.x/
11+
- - https://www.sphinx-doc.org/en/master/
1212
- - null

tests/test_seeding_/test_sphinx_seed_intersphinx_mapping_mocked_bad_example_requirements_requirements_.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ packaging:
88
- - null
99
sphinx:
1010
- sphinx
11-
- - https://www.sphinx-doc.org/en/3.x/
11+
- - https://www.sphinx-doc.org/en/master/
1212
- - null

tests/test_seeding_/test_sphinx_seed_intersphinx_mapping_mocked_example_requirements_a_flit_.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@ slumber:
1616
- - null
1717
sphinx:
1818
- sphinx
19-
- - https://www.sphinx-doc.org/en/3.x/
19+
- - https://www.sphinx-doc.org/en/master/
2020
- - null

0 commit comments

Comments
 (0)