intersphinx: Normalize mapping on config-inited

This commit is contained in:
Takeshi KOMIYA 2018-11-04 20:22:50 +09:00
parent 0a199c08b8
commit 556f599e6e
2 changed files with 38 additions and 24 deletions

View File

@ -204,28 +204,7 @@ def load_mappings(app):
cache_time = now - app.config.intersphinx_cache_limit * 86400
inventories = InventoryAdapter(app.builder.env)
update = False
for key, value in app.config.intersphinx_mapping.items():
name = None # type: str
uri = None # type: str
inv = None # type: Union[str, Tuple[str, ...]]
if isinstance(value, (list, tuple)):
# new format
name, (uri, inv) = key, value
if not isinstance(name, str):
logger.warning(__('intersphinx identifier %r is not string. Ignored'), name)
continue
else:
# old format, no name
name, uri, inv = None, key, value
# we can safely assume that the uri<->inv mapping is not changed
# during partial rebuilds since a changed intersphinx_mapping
# setting will cause a full environment reread
if not isinstance(inv, tuple):
invs = (inv, )
else:
invs = inv # type: ignore
for key, (name, (uri, invs)) in app.config.intersphinx_mapping.items():
failures = []
for inv in invs:
if not inv:
@ -358,13 +337,39 @@ def missing_reference(app, env, node, contnode):
return None
def normalize_intersphinx_mapping(app, config):
# type: (Sphinx, Config) -> None
for key, value in config.intersphinx_mapping.copy().items():
try:
if isinstance(value, (list, tuple)):
# new format
name, (uri, inv) = key, value
if not isinstance(name, str):
logger.warning(__('intersphinx identifier %r is not string. Ignored'),
name)
config.intersphinx_mapping.pop(key)
continue
else:
# old format, no name
name, uri, inv = None, key, value
if not isinstance(inv, tuple):
config.intersphinx_mapping[key] = (name, (uri, (inv,)))
else:
config.intersphinx_mapping[key] = (name, (uri, inv))
except Exception as exc:
logger.warning(__('Fail to read intersphinx_mapping[%s], Ignored: %r'), key, exc)
config.intersphinx_mapping.pop(key)
def setup(app):
# type: (Sphinx) -> Dict[str, Any]
app.add_config_value('intersphinx_mapping', {}, True)
app.add_config_value('intersphinx_cache_limit', 5, False)
app.add_config_value('intersphinx_timeout', None, False)
app.connect('missing-reference', missing_reference)
app.connect('config-inited', normalize_intersphinx_mapping)
app.connect('builder-inited', load_mappings)
app.connect('missing-reference', missing_reference)
return {
'version': sphinx.__display_version__,
'env_version': 1,

View File

@ -20,7 +20,7 @@ from test_util_inventory import inventory_v2, inventory_v2_not_having_version
from sphinx import addnodes
from sphinx.ext.intersphinx import (
load_mappings, missing_reference, _strip_basic_auth,
load_mappings, missing_reference, normalize_intersphinx_mapping, _strip_basic_auth,
_get_safe_url, fetch_inventory, INVENTORY_FILENAME, inspect_main
)
from sphinx.ext.intersphinx import setup as intersphinx_setup
@ -99,6 +99,7 @@ def test_missing_reference(tempdir, app, status, warning):
app.config.intersphinx_cache_limit = 0
# load the inventory and check if it's done correctly
normalize_intersphinx_mapping(app, app.config)
load_mappings(app)
inv = app.env.intersphinx_inventory
@ -174,6 +175,7 @@ def test_missing_reference_pydomain(tempdir, app, status, warning):
app.config.intersphinx_cache_limit = 0
# load the inventory and check if it's done correctly
normalize_intersphinx_mapping(app, app.config)
load_mappings(app)
# no context data
@ -198,6 +200,7 @@ def test_missing_reference_stddomain(tempdir, app, status, warning):
app.config.intersphinx_cache_limit = 0
# load the inventory and check if it's done correctly
normalize_intersphinx_mapping(app, app.config)
load_mappings(app)
# no context data
@ -229,6 +232,7 @@ def test_missing_reference_cppdomain(tempdir, app, status, warning):
app.config.intersphinx_cache_limit = 0
# load the inventory and check if it's done correctly
normalize_intersphinx_mapping(app, app.config)
load_mappings(app)
app.build()
@ -255,6 +259,7 @@ def test_missing_reference_jsdomain(tempdir, app, status, warning):
app.config.intersphinx_cache_limit = 0
# load the inventory and check if it's done correctly
normalize_intersphinx_mapping(app, app.config)
load_mappings(app)
# no context data
@ -280,6 +285,7 @@ def test_inventory_not_having_version(tempdir, app, status, warning):
app.config.intersphinx_cache_limit = 0
# load the inventory and check if it's done correctly
normalize_intersphinx_mapping(app, app.config)
load_mappings(app)
rn = reference_check(app, 'py', 'mod', 'module1', 'foo')
@ -307,6 +313,7 @@ def test_load_mappings_warnings(tempdir, app, status, warning):
app.config.intersphinx_cache_limit = 0
# load the inventory and check if it's done correctly
normalize_intersphinx_mapping(app, app.config)
load_mappings(app)
assert warning.getvalue().count('\n') == 1
@ -320,6 +327,7 @@ def test_load_mappings_fallback(tempdir, app, status, warning):
app.config.intersphinx_mapping = {
'fallback': ('https://docs.python.org/py3k/', '/invalid/inventory/path'),
}
normalize_intersphinx_mapping(app, app.config)
load_mappings(app)
assert "failed to reach any of the inventories" in warning.getvalue()
@ -335,6 +343,7 @@ def test_load_mappings_fallback(tempdir, app, status, warning):
'fallback': ('https://docs.python.org/py3k/', ('/invalid/inventory/path',
inv_file)),
}
normalize_intersphinx_mapping(app, app.config)
load_mappings(app)
assert "encountered some issues with some of the inventories" in status.getvalue()
assert "" == warning.getvalue()