Sphinx 8.1.2__py3-none-any.whl → 8.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of Sphinx might be problematic. Click here for more details.
- sphinx/__init__.py +8 -4
- sphinx/__main__.py +2 -0
- sphinx/_cli/__init__.py +2 -5
- sphinx/_cli/util/colour.py +34 -11
- sphinx/_cli/util/errors.py +128 -61
- sphinx/addnodes.py +51 -35
- sphinx/application.py +362 -230
- sphinx/builders/__init__.py +87 -64
- sphinx/builders/_epub_base.py +65 -56
- sphinx/builders/changes.py +17 -23
- sphinx/builders/dirhtml.py +8 -13
- sphinx/builders/epub3.py +70 -38
- sphinx/builders/gettext.py +93 -73
- sphinx/builders/html/__init__.py +240 -186
- sphinx/builders/html/_assets.py +9 -2
- sphinx/builders/html/_build_info.py +3 -0
- sphinx/builders/latex/__init__.py +64 -54
- sphinx/builders/latex/constants.py +14 -11
- sphinx/builders/latex/nodes.py +2 -0
- sphinx/builders/latex/theming.py +8 -9
- sphinx/builders/latex/transforms.py +7 -5
- sphinx/builders/linkcheck.py +193 -149
- sphinx/builders/manpage.py +17 -17
- sphinx/builders/singlehtml.py +28 -16
- sphinx/builders/texinfo.py +28 -21
- sphinx/builders/text.py +10 -15
- sphinx/builders/xml.py +10 -19
- sphinx/cmd/build.py +49 -119
- sphinx/cmd/make_mode.py +35 -31
- sphinx/cmd/quickstart.py +78 -62
- sphinx/config.py +265 -163
- sphinx/directives/__init__.py +51 -54
- sphinx/directives/admonitions.py +107 -0
- sphinx/directives/code.py +24 -19
- sphinx/directives/other.py +21 -42
- sphinx/directives/patches.py +28 -16
- sphinx/domains/__init__.py +54 -31
- sphinx/domains/_domains_container.py +22 -17
- sphinx/domains/_index.py +5 -8
- sphinx/domains/c/__init__.py +366 -245
- sphinx/domains/c/_ast.py +378 -256
- sphinx/domains/c/_ids.py +89 -31
- sphinx/domains/c/_parser.py +283 -214
- sphinx/domains/c/_symbol.py +269 -198
- sphinx/domains/changeset.py +39 -24
- sphinx/domains/citation.py +54 -24
- sphinx/domains/cpp/__init__.py +517 -362
- sphinx/domains/cpp/_ast.py +999 -682
- sphinx/domains/cpp/_ids.py +133 -65
- sphinx/domains/cpp/_parser.py +746 -588
- sphinx/domains/cpp/_symbol.py +692 -489
- sphinx/domains/index.py +10 -8
- sphinx/domains/javascript.py +152 -74
- sphinx/domains/math.py +50 -40
- sphinx/domains/python/__init__.py +402 -211
- sphinx/domains/python/_annotations.py +134 -61
- sphinx/domains/python/_object.py +155 -68
- sphinx/domains/rst.py +94 -49
- sphinx/domains/std/__init__.py +510 -249
- sphinx/environment/__init__.py +345 -61
- sphinx/environment/adapters/asset.py +7 -1
- sphinx/environment/adapters/indexentries.py +15 -20
- sphinx/environment/adapters/toctree.py +19 -9
- sphinx/environment/collectors/__init__.py +3 -1
- sphinx/environment/collectors/asset.py +18 -15
- sphinx/environment/collectors/dependencies.py +8 -10
- sphinx/environment/collectors/metadata.py +6 -4
- sphinx/environment/collectors/title.py +3 -1
- sphinx/environment/collectors/toctree.py +4 -4
- sphinx/errors.py +1 -3
- sphinx/events.py +4 -4
- sphinx/ext/apidoc/__init__.py +66 -0
- sphinx/ext/apidoc/__main__.py +9 -0
- sphinx/ext/apidoc/_cli.py +356 -0
- sphinx/ext/apidoc/_extension.py +262 -0
- sphinx/ext/apidoc/_generate.py +356 -0
- sphinx/ext/apidoc/_shared.py +99 -0
- sphinx/ext/autodoc/__init__.py +837 -483
- sphinx/ext/autodoc/directive.py +57 -21
- sphinx/ext/autodoc/importer.py +184 -67
- sphinx/ext/autodoc/mock.py +25 -10
- sphinx/ext/autodoc/preserve_defaults.py +17 -9
- sphinx/ext/autodoc/type_comment.py +56 -29
- sphinx/ext/autodoc/typehints.py +49 -26
- sphinx/ext/autosectionlabel.py +28 -11
- sphinx/ext/autosummary/__init__.py +281 -142
- sphinx/ext/autosummary/generate.py +121 -51
- sphinx/ext/coverage.py +152 -91
- sphinx/ext/doctest.py +169 -101
- sphinx/ext/duration.py +12 -6
- sphinx/ext/extlinks.py +33 -21
- sphinx/ext/githubpages.py +8 -8
- sphinx/ext/graphviz.py +175 -109
- sphinx/ext/ifconfig.py +11 -6
- sphinx/ext/imgconverter.py +48 -25
- sphinx/ext/imgmath.py +127 -97
- sphinx/ext/inheritance_diagram.py +177 -103
- sphinx/ext/intersphinx/__init__.py +22 -13
- sphinx/ext/intersphinx/__main__.py +3 -1
- sphinx/ext/intersphinx/_cli.py +18 -14
- sphinx/ext/intersphinx/_load.py +91 -82
- sphinx/ext/intersphinx/_resolve.py +108 -74
- sphinx/ext/intersphinx/_shared.py +2 -2
- sphinx/ext/linkcode.py +28 -12
- sphinx/ext/mathjax.py +60 -29
- sphinx/ext/napoleon/__init__.py +19 -7
- sphinx/ext/napoleon/docstring.py +229 -231
- sphinx/ext/todo.py +44 -49
- sphinx/ext/viewcode.py +105 -57
- sphinx/extension.py +3 -1
- sphinx/highlighting.py +13 -7
- sphinx/io.py +9 -13
- sphinx/jinja2glue.py +29 -26
- sphinx/locale/__init__.py +8 -9
- sphinx/locale/ar/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ar/LC_MESSAGES/sphinx.po +2155 -2050
- sphinx/locale/bg/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/bg/LC_MESSAGES/sphinx.po +2045 -1940
- sphinx/locale/bn/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/bn/LC_MESSAGES/sphinx.po +2175 -2070
- sphinx/locale/ca/LC_MESSAGES/sphinx.js +3 -3
- sphinx/locale/ca/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ca/LC_MESSAGES/sphinx.po +2690 -2585
- sphinx/locale/ca@valencia/LC_MESSAGES/sphinx.js +63 -0
- sphinx/locale/ca@valencia/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ca@valencia/LC_MESSAGES/sphinx.po +4216 -0
- sphinx/locale/cak/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/cak/LC_MESSAGES/sphinx.po +2096 -1991
- sphinx/locale/cs/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/cs/LC_MESSAGES/sphinx.po +2248 -2143
- sphinx/locale/cy/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/cy/LC_MESSAGES/sphinx.po +2201 -2096
- sphinx/locale/da/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/da/LC_MESSAGES/sphinx.po +2282 -2177
- sphinx/locale/de/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/de/LC_MESSAGES/sphinx.po +2261 -2156
- sphinx/locale/de_DE/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/de_DE/LC_MESSAGES/sphinx.po +2045 -1940
- sphinx/locale/el/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/el/LC_MESSAGES/sphinx.po +2604 -2499
- sphinx/locale/en_DE/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/en_DE/LC_MESSAGES/sphinx.po +2045 -1940
- sphinx/locale/en_FR/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/en_FR/LC_MESSAGES/sphinx.po +2045 -1940
- sphinx/locale/en_GB/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/en_GB/LC_MESSAGES/sphinx.po +2631 -2526
- sphinx/locale/en_HK/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/en_HK/LC_MESSAGES/sphinx.po +2045 -1940
- sphinx/locale/eo/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/eo/LC_MESSAGES/sphinx.po +2078 -1973
- sphinx/locale/es/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/es/LC_MESSAGES/sphinx.po +2633 -2528
- sphinx/locale/es_CO/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/es_CO/LC_MESSAGES/sphinx.po +2045 -1940
- sphinx/locale/et/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/et/LC_MESSAGES/sphinx.po +2449 -2344
- sphinx/locale/eu/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/eu/LC_MESSAGES/sphinx.po +2241 -2136
- sphinx/locale/fa/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/fa/LC_MESSAGES/sphinx.po +504 -500
- sphinx/locale/fi/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/fi/LC_MESSAGES/sphinx.po +499 -495
- sphinx/locale/fr/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/fr/LC_MESSAGES/sphinx.po +513 -509
- sphinx/locale/fr_FR/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/fr_FR/LC_MESSAGES/sphinx.po +499 -495
- sphinx/locale/gl/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/gl/LC_MESSAGES/sphinx.po +2644 -2539
- sphinx/locale/he/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/he/LC_MESSAGES/sphinx.po +499 -495
- sphinx/locale/hi/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/hi/LC_MESSAGES/sphinx.po +504 -500
- sphinx/locale/hi_IN/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/hi_IN/LC_MESSAGES/sphinx.po +499 -495
- sphinx/locale/hr/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/hr/LC_MESSAGES/sphinx.po +501 -497
- sphinx/locale/hu/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/hu/LC_MESSAGES/sphinx.po +499 -495
- sphinx/locale/id/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/id/LC_MESSAGES/sphinx.po +2609 -2504
- sphinx/locale/is/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/is/LC_MESSAGES/sphinx.po +499 -495
- sphinx/locale/it/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/it/LC_MESSAGES/sphinx.po +2265 -2160
- sphinx/locale/ja/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ja/LC_MESSAGES/sphinx.po +2621 -2516
- sphinx/locale/ka/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ka/LC_MESSAGES/sphinx.po +2567 -2462
- sphinx/locale/ko/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ko/LC_MESSAGES/sphinx.po +2631 -2526
- sphinx/locale/lt/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/lt/LC_MESSAGES/sphinx.po +2214 -2109
- sphinx/locale/lv/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/lv/LC_MESSAGES/sphinx.po +2218 -2113
- sphinx/locale/mk/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/mk/LC_MESSAGES/sphinx.po +2088 -1983
- sphinx/locale/nb_NO/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/nb_NO/LC_MESSAGES/sphinx.po +2247 -2142
- sphinx/locale/ne/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ne/LC_MESSAGES/sphinx.po +2227 -2122
- sphinx/locale/nl/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/nl/LC_MESSAGES/sphinx.po +2316 -2211
- sphinx/locale/pl/LC_MESSAGES/sphinx.js +2 -2
- sphinx/locale/pl/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/pl/LC_MESSAGES/sphinx.po +2442 -2336
- sphinx/locale/pt/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/pt/LC_MESSAGES/sphinx.po +2045 -1940
- sphinx/locale/pt_BR/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/pt_BR/LC_MESSAGES/sphinx.po +2657 -2552
- sphinx/locale/pt_PT/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/pt_PT/LC_MESSAGES/sphinx.po +2243 -2138
- sphinx/locale/ro/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ro/LC_MESSAGES/sphinx.po +2244 -2139
- sphinx/locale/ru/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/ru/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ru/LC_MESSAGES/sphinx.po +2660 -2555
- sphinx/locale/si/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/si/LC_MESSAGES/sphinx.po +2134 -2029
- sphinx/locale/sk/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sk/LC_MESSAGES/sphinx.po +2614 -2509
- sphinx/locale/sl/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sl/LC_MESSAGES/sphinx.po +2167 -2062
- sphinx/locale/sphinx.pot +2069 -1964
- sphinx/locale/sq/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sq/LC_MESSAGES/sphinx.po +2661 -2556
- sphinx/locale/sr/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sr/LC_MESSAGES/sphinx.po +2213 -2108
- sphinx/locale/sv/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sv/LC_MESSAGES/sphinx.po +2229 -2124
- sphinx/locale/te/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/te/LC_MESSAGES/sphinx.po +2045 -1940
- sphinx/locale/tr/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/tr/LC_MESSAGES/sphinx.po +2608 -2503
- sphinx/locale/uk_UA/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/uk_UA/LC_MESSAGES/sphinx.po +2167 -2062
- sphinx/locale/ur/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ur/LC_MESSAGES/sphinx.po +2045 -1940
- sphinx/locale/vi/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/vi/LC_MESSAGES/sphinx.po +2204 -2099
- sphinx/locale/yue/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/yue/LC_MESSAGES/sphinx.po +2045 -1940
- sphinx/locale/zh_HK/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/zh_HK/LC_MESSAGES/sphinx.po +2045 -1940
- sphinx/locale/zh_TW/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/zh_TW/LC_MESSAGES/sphinx.po +2659 -2554
- sphinx/locale/zh_TW.Big5/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/zh_TW.Big5/LC_MESSAGES/sphinx.po +2045 -1940
- sphinx/parsers.py +8 -7
- sphinx/project.py +2 -2
- sphinx/pycode/__init__.py +31 -21
- sphinx/pycode/ast.py +6 -3
- sphinx/pycode/parser.py +14 -8
- sphinx/pygments_styles.py +4 -5
- sphinx/registry.py +192 -92
- sphinx/roles.py +58 -7
- sphinx/search/__init__.py +75 -54
- sphinx/search/en.py +11 -13
- sphinx/search/fi.py +1 -1
- sphinx/search/ja.py +8 -6
- sphinx/search/nl.py +1 -1
- sphinx/search/zh.py +19 -21
- sphinx/testing/fixtures.py +26 -29
- sphinx/testing/path.py +26 -62
- sphinx/testing/restructuredtext.py +14 -8
- sphinx/testing/util.py +21 -19
- sphinx/texinputs/make.bat.jinja +50 -50
- sphinx/texinputs/sphinx.sty +4 -3
- sphinx/texinputs/sphinxlatexadmonitions.sty +1 -1
- sphinx/texinputs/sphinxlatexobjects.sty +29 -10
- sphinx/themes/basic/static/searchtools.js +8 -5
- sphinx/theming.py +49 -61
- sphinx/transforms/__init__.py +17 -38
- sphinx/transforms/compact_bullet_list.py +5 -3
- sphinx/transforms/i18n.py +8 -21
- sphinx/transforms/post_transforms/__init__.py +142 -93
- sphinx/transforms/post_transforms/code.py +5 -5
- sphinx/transforms/post_transforms/images.py +28 -24
- sphinx/transforms/references.py +3 -1
- sphinx/util/__init__.py +109 -60
- sphinx/util/_files.py +39 -23
- sphinx/util/_importer.py +4 -1
- sphinx/util/_inventory_file_reader.py +76 -0
- sphinx/util/_io.py +2 -2
- sphinx/util/_lines.py +6 -3
- sphinx/util/_pathlib.py +40 -2
- sphinx/util/build_phase.py +2 -0
- sphinx/util/cfamily.py +19 -14
- sphinx/util/console.py +44 -179
- sphinx/util/display.py +9 -10
- sphinx/util/docfields.py +140 -122
- sphinx/util/docstrings.py +1 -1
- sphinx/util/docutils.py +118 -77
- sphinx/util/fileutil.py +25 -26
- sphinx/util/http_date.py +2 -0
- sphinx/util/i18n.py +77 -64
- sphinx/util/images.py +8 -6
- sphinx/util/inspect.py +147 -38
- sphinx/util/inventory.py +215 -116
- sphinx/util/logging.py +33 -33
- sphinx/util/matching.py +12 -4
- sphinx/util/nodes.py +18 -13
- sphinx/util/osutil.py +38 -39
- sphinx/util/parallel.py +22 -13
- sphinx/util/parsing.py +2 -1
- sphinx/util/png.py +6 -2
- sphinx/util/requests.py +33 -2
- sphinx/util/rst.py +3 -2
- sphinx/util/tags.py +1 -1
- sphinx/util/template.py +18 -10
- sphinx/util/texescape.py +8 -6
- sphinx/util/typing.py +148 -122
- sphinx/versioning.py +3 -3
- sphinx/writers/html.py +3 -1
- sphinx/writers/html5.py +63 -52
- sphinx/writers/latex.py +83 -67
- sphinx/writers/manpage.py +19 -38
- sphinx/writers/texinfo.py +47 -47
- sphinx/writers/text.py +50 -32
- sphinx/writers/xml.py +11 -8
- {sphinx-8.1.2.dist-info → sphinx-8.2.0.dist-info}/LICENSE.rst +1 -1
- {sphinx-8.1.2.dist-info → sphinx-8.2.0.dist-info}/METADATA +25 -15
- sphinx-8.2.0.dist-info/RECORD +606 -0
- {sphinx-8.1.2.dist-info → sphinx-8.2.0.dist-info}/WHEEL +1 -1
- sphinx/builders/html/transforms.py +0 -90
- sphinx/ext/apidoc.py +0 -721
- sphinx/util/exceptions.py +0 -74
- sphinx-8.1.2.dist-info/RECORD +0 -598
- {sphinx-8.1.2.dist-info → sphinx-8.2.0.dist-info}/entry_points.txt +0 -0
sphinx/ext/intersphinx/_load.py
CHANGED
|
@@ -3,10 +3,11 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import concurrent.futures
|
|
6
|
+
import dataclasses
|
|
7
|
+
import os.path
|
|
6
8
|
import posixpath
|
|
7
9
|
import time
|
|
8
10
|
from operator import itemgetter
|
|
9
|
-
from os import path
|
|
10
11
|
from typing import TYPE_CHECKING
|
|
11
12
|
from urllib.parse import urlsplit, urlunsplit
|
|
12
13
|
|
|
@@ -20,8 +21,6 @@ from sphinx.util.inventory import InventoryFile
|
|
|
20
21
|
if TYPE_CHECKING:
|
|
21
22
|
from pathlib import Path
|
|
22
23
|
|
|
23
|
-
from urllib3.response import HTTPResponse
|
|
24
|
-
|
|
25
24
|
from sphinx.application import Sphinx
|
|
26
25
|
from sphinx.config import Config
|
|
27
26
|
from sphinx.ext.intersphinx._shared import (
|
|
@@ -31,7 +30,8 @@ if TYPE_CHECKING:
|
|
|
31
30
|
InventoryName,
|
|
32
31
|
InventoryURI,
|
|
33
32
|
)
|
|
34
|
-
from sphinx.util.
|
|
33
|
+
from sphinx.util.inventory import _Inventory
|
|
34
|
+
from sphinx.util.typing import Inventory
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
def validate_intersphinx_mapping(app: Sphinx, config: Config) -> None:
|
|
@@ -82,7 +82,7 @@ def validate_intersphinx_mapping(app: Sphinx, config: Config) -> None:
|
|
|
82
82
|
'Invalid value `%r` in intersphinx_mapping[%r]. '
|
|
83
83
|
'Values must be a (target URI, inventory locations) pair.'
|
|
84
84
|
)
|
|
85
|
-
LOGGER.error(msg, value, name)
|
|
85
|
+
LOGGER.error(msg, value, name) # NoQA: TRY400
|
|
86
86
|
del config.intersphinx_mapping[name]
|
|
87
87
|
continue
|
|
88
88
|
|
|
@@ -140,8 +140,9 @@ def load_mappings(app: Sphinx) -> None:
|
|
|
140
140
|
|
|
141
141
|
The intersphinx mappings are expected to be normalized.
|
|
142
142
|
"""
|
|
143
|
+
env = app.env
|
|
143
144
|
now = int(time.time())
|
|
144
|
-
inventories = InventoryAdapter(
|
|
145
|
+
inventories = InventoryAdapter(env)
|
|
145
146
|
intersphinx_cache: dict[InventoryURI, InventoryCacheEntry] = inventories.cache
|
|
146
147
|
intersphinx_mapping: IntersphinxMapping = app.config.intersphinx_mapping
|
|
147
148
|
|
|
@@ -170,6 +171,7 @@ def load_mappings(app: Sphinx) -> None:
|
|
|
170
171
|
# This happens when the URI in `intersphinx_mapping` is changed.
|
|
171
172
|
del intersphinx_cache[uri]
|
|
172
173
|
|
|
174
|
+
inv_config = _InvConfig.from_config(app.config)
|
|
173
175
|
with concurrent.futures.ThreadPoolExecutor() as pool:
|
|
174
176
|
futures = [
|
|
175
177
|
pool.submit(
|
|
@@ -177,7 +179,7 @@ def load_mappings(app: Sphinx) -> None:
|
|
|
177
179
|
project=project,
|
|
178
180
|
cache=intersphinx_cache,
|
|
179
181
|
now=now,
|
|
180
|
-
config=
|
|
182
|
+
config=inv_config,
|
|
181
183
|
srcdir=app.srcdir,
|
|
182
184
|
)
|
|
183
185
|
for project in projects
|
|
@@ -202,12 +204,31 @@ def load_mappings(app: Sphinx) -> None:
|
|
|
202
204
|
inventories.main_inventory.setdefault(objtype, {}).update(objects)
|
|
203
205
|
|
|
204
206
|
|
|
207
|
+
@dataclasses.dataclass(frozen=True, kw_only=True, slots=True)
|
|
208
|
+
class _InvConfig:
|
|
209
|
+
intersphinx_cache_limit: int
|
|
210
|
+
intersphinx_timeout: int | float | None
|
|
211
|
+
tls_verify: bool
|
|
212
|
+
tls_cacerts: str | dict[str, str] | None
|
|
213
|
+
user_agent: str
|
|
214
|
+
|
|
215
|
+
@classmethod
|
|
216
|
+
def from_config(cls, config: Config) -> _InvConfig:
|
|
217
|
+
return cls(
|
|
218
|
+
intersphinx_cache_limit=config.intersphinx_cache_limit,
|
|
219
|
+
intersphinx_timeout=config.intersphinx_timeout,
|
|
220
|
+
tls_verify=config.tls_verify,
|
|
221
|
+
tls_cacerts=config.tls_cacerts,
|
|
222
|
+
user_agent=config.user_agent,
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
|
|
205
226
|
def _fetch_inventory_group(
|
|
206
227
|
*,
|
|
207
228
|
project: _IntersphinxProject,
|
|
208
229
|
cache: dict[InventoryURI, InventoryCacheEntry],
|
|
209
230
|
now: int,
|
|
210
|
-
config:
|
|
231
|
+
config: _InvConfig,
|
|
211
232
|
srcdir: Path,
|
|
212
233
|
) -> bool:
|
|
213
234
|
if config.intersphinx_cache_limit >= 0:
|
|
@@ -225,27 +246,27 @@ def _fetch_inventory_group(
|
|
|
225
246
|
for location in project.locations:
|
|
226
247
|
# location is either None or a non-empty string
|
|
227
248
|
if location is None:
|
|
228
|
-
|
|
249
|
+
inv_location = posixpath.join(project.target_uri, INVENTORY_FILENAME)
|
|
229
250
|
else:
|
|
230
|
-
|
|
251
|
+
inv_location = location
|
|
231
252
|
|
|
232
253
|
# decide whether the inventory must be read: always read local
|
|
233
254
|
# files; remote ones only if the cache time is expired
|
|
234
255
|
if (
|
|
235
|
-
'://' not in
|
|
256
|
+
'://' not in inv_location
|
|
236
257
|
or project.target_uri not in cache
|
|
237
258
|
or cache[project.target_uri][1] < cache_time
|
|
238
259
|
):
|
|
239
260
|
LOGGER.info(
|
|
240
261
|
__("loading intersphinx inventory '%s' from %s ..."),
|
|
241
262
|
project.name,
|
|
242
|
-
_get_safe_url(
|
|
263
|
+
_get_safe_url(inv_location),
|
|
243
264
|
)
|
|
244
265
|
|
|
245
266
|
try:
|
|
246
|
-
|
|
267
|
+
inv = _fetch_inventory(
|
|
247
268
|
target_uri=project.target_uri,
|
|
248
|
-
inv_location=
|
|
269
|
+
inv_location=inv_location,
|
|
249
270
|
config=config,
|
|
250
271
|
srcdir=srcdir,
|
|
251
272
|
)
|
|
@@ -253,8 +274,8 @@ def _fetch_inventory_group(
|
|
|
253
274
|
failures.append(err.args)
|
|
254
275
|
continue
|
|
255
276
|
|
|
256
|
-
if
|
|
257
|
-
cache[project.target_uri] = project.name, now,
|
|
277
|
+
if inv:
|
|
278
|
+
cache[project.target_uri] = project.name, now, inv.data
|
|
258
279
|
updated = True
|
|
259
280
|
break
|
|
260
281
|
|
|
@@ -272,9 +293,9 @@ def _fetch_inventory_group(
|
|
|
272
293
|
else:
|
|
273
294
|
issues = '\n'.join(f[0] % f[1:] for f in failures)
|
|
274
295
|
LOGGER.warning(
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
296
|
+
'%s\n%s',
|
|
297
|
+
__('failed to reach any of the inventories with the following issues:'),
|
|
298
|
+
issues,
|
|
278
299
|
)
|
|
279
300
|
return updated
|
|
280
301
|
|
|
@@ -284,26 +305,49 @@ def fetch_inventory(app: Sphinx, uri: InventoryURI, inv: str) -> Inventory:
|
|
|
284
305
|
return _fetch_inventory(
|
|
285
306
|
target_uri=uri,
|
|
286
307
|
inv_location=inv,
|
|
287
|
-
config=app.config,
|
|
308
|
+
config=_InvConfig.from_config(app.config),
|
|
288
309
|
srcdir=app.srcdir,
|
|
289
|
-
)
|
|
310
|
+
).data
|
|
290
311
|
|
|
291
312
|
|
|
292
313
|
def _fetch_inventory(
|
|
293
|
-
*, target_uri: InventoryURI, inv_location: str, config:
|
|
294
|
-
) ->
|
|
314
|
+
*, target_uri: InventoryURI, inv_location: str, config: _InvConfig, srcdir: Path
|
|
315
|
+
) -> _Inventory:
|
|
295
316
|
"""Fetch, parse and return an intersphinx inventory file."""
|
|
296
317
|
# both *target_uri* (base URI of the links to generate)
|
|
297
318
|
# and *inv_location* (actual location of the inventory file)
|
|
298
319
|
# can be local or remote URIs
|
|
299
320
|
if '://' in target_uri:
|
|
300
|
-
#
|
|
321
|
+
# inv URI points to remote resource; strip any existing auth
|
|
301
322
|
target_uri = _strip_basic_auth(target_uri)
|
|
323
|
+
if '://' in inv_location:
|
|
324
|
+
raw_data, target_uri = _fetch_inventory_url(
|
|
325
|
+
target_uri=target_uri, inv_location=inv_location, config=config
|
|
326
|
+
)
|
|
327
|
+
else:
|
|
328
|
+
raw_data = _fetch_inventory_file(inv_location=inv_location, srcdir=srcdir)
|
|
329
|
+
|
|
302
330
|
try:
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
331
|
+
inv = InventoryFile.loads(raw_data, uri=target_uri)
|
|
332
|
+
except ValueError as exc:
|
|
333
|
+
msg = f'unknown or unsupported inventory version: {exc!r}'
|
|
334
|
+
raise ValueError(msg) from exc
|
|
335
|
+
return inv
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
def _fetch_inventory_url(
|
|
339
|
+
*, target_uri: InventoryURI, inv_location: str, config: _InvConfig
|
|
340
|
+
) -> tuple[bytes, str]:
|
|
341
|
+
try:
|
|
342
|
+
with requests.get(
|
|
343
|
+
inv_location,
|
|
344
|
+
timeout=config.intersphinx_timeout,
|
|
345
|
+
_user_agent=config.user_agent,
|
|
346
|
+
_tls_info=(config.tls_verify, config.tls_cacerts),
|
|
347
|
+
) as r:
|
|
348
|
+
r.raise_for_status()
|
|
349
|
+
raw_data = r.content
|
|
350
|
+
new_inv_location = r.url
|
|
307
351
|
except Exception as err:
|
|
308
352
|
err.args = (
|
|
309
353
|
'intersphinx inventory %r not fetchable due to %s: %s',
|
|
@@ -312,25 +356,25 @@ def _fetch_inventory(
|
|
|
312
356
|
str(err),
|
|
313
357
|
)
|
|
314
358
|
raise
|
|
359
|
+
|
|
360
|
+
if inv_location != new_inv_location:
|
|
361
|
+
msg = __('intersphinx inventory has moved: %s -> %s')
|
|
362
|
+
LOGGER.info(msg, inv_location, new_inv_location)
|
|
363
|
+
|
|
364
|
+
if target_uri in {
|
|
365
|
+
inv_location,
|
|
366
|
+
os.path.dirname(inv_location),
|
|
367
|
+
os.path.dirname(inv_location) + '/',
|
|
368
|
+
}:
|
|
369
|
+
target_uri = os.path.dirname(new_inv_location)
|
|
370
|
+
|
|
371
|
+
return raw_data, target_uri
|
|
372
|
+
|
|
373
|
+
|
|
374
|
+
def _fetch_inventory_file(*, inv_location: str, srcdir: Path) -> bytes:
|
|
315
375
|
try:
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
if inv_location != new_inv_location:
|
|
319
|
-
msg = __('intersphinx inventory has moved: %s -> %s')
|
|
320
|
-
LOGGER.info(msg, inv_location, new_inv_location)
|
|
321
|
-
|
|
322
|
-
if target_uri in {
|
|
323
|
-
inv_location,
|
|
324
|
-
path.dirname(inv_location),
|
|
325
|
-
path.dirname(inv_location) + '/',
|
|
326
|
-
}:
|
|
327
|
-
target_uri = path.dirname(new_inv_location)
|
|
328
|
-
with f:
|
|
329
|
-
try:
|
|
330
|
-
invdata = InventoryFile.load(f, target_uri, posixpath.join)
|
|
331
|
-
except ValueError as exc:
|
|
332
|
-
msg = f'unknown or unsupported inventory version: {exc!r}'
|
|
333
|
-
raise ValueError(msg) from exc
|
|
376
|
+
with open(srcdir / inv_location, 'rb') as f:
|
|
377
|
+
raw_data = f.read()
|
|
334
378
|
except Exception as err:
|
|
335
379
|
err.args = (
|
|
336
380
|
'intersphinx inventory %r not readable due to %s: %s',
|
|
@@ -339,8 +383,7 @@ def _fetch_inventory(
|
|
|
339
383
|
str(err),
|
|
340
384
|
)
|
|
341
385
|
raise
|
|
342
|
-
|
|
343
|
-
return invdata
|
|
386
|
+
return raw_data
|
|
344
387
|
|
|
345
388
|
|
|
346
389
|
def _get_safe_url(url: str) -> str:
|
|
@@ -387,37 +430,3 @@ def _strip_basic_auth(url: str) -> str:
|
|
|
387
430
|
if '@' in frags[1]:
|
|
388
431
|
frags[1] = frags[1].split('@')[1]
|
|
389
432
|
return urlunsplit(frags)
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
def _read_from_url(url: str, *, config: Config) -> HTTPResponse:
|
|
393
|
-
"""Reads data from *url* with an HTTP *GET*.
|
|
394
|
-
|
|
395
|
-
This function supports fetching from resources which use basic HTTP auth as
|
|
396
|
-
laid out by RFC1738 § 3.1. See § 5 for grammar definitions for URLs.
|
|
397
|
-
|
|
398
|
-
.. seealso:
|
|
399
|
-
|
|
400
|
-
https://www.ietf.org/rfc/rfc1738.txt
|
|
401
|
-
|
|
402
|
-
:param url: URL of an HTTP resource
|
|
403
|
-
:type url: ``str``
|
|
404
|
-
|
|
405
|
-
:return: data read from resource described by *url*
|
|
406
|
-
:rtype: ``file``-like object
|
|
407
|
-
"""
|
|
408
|
-
r = requests.get(
|
|
409
|
-
url,
|
|
410
|
-
stream=True,
|
|
411
|
-
timeout=config.intersphinx_timeout,
|
|
412
|
-
_user_agent=config.user_agent,
|
|
413
|
-
_tls_info=(config.tls_verify, config.tls_cacerts),
|
|
414
|
-
)
|
|
415
|
-
r.raise_for_status()
|
|
416
|
-
|
|
417
|
-
# For inv_location / new_inv_location
|
|
418
|
-
r.raw.url = r.url # type: ignore[union-attr]
|
|
419
|
-
|
|
420
|
-
# Decode content-body based on the header.
|
|
421
|
-
# xref: https://github.com/psf/requests/issues/2155
|
|
422
|
-
r.raw.decode_content = True
|
|
423
|
-
return r.raw
|