Rename `normalize_intersphinx_mapping to validate_intersphinx_mapping` (#12643)

This commit is contained in:
Adam Turner 2024-07-22 13:32:44 +01:00 committed by GitHub
parent aacca3064e
commit e174df2762
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 73 additions and 30 deletions

View File

@ -67,6 +67,11 @@ Incompatible changes
Deprecated
----------
* #12643: Renamed ``sphinx.ext.intersphinx.normalize_intersphinx_mapping``
to ``sphinx.ext.intersphinx.validate_intersphinx_mapping``.
The old name will be removed in Sphinx 10.
Patch by Adam Turner.
Features added
--------------

View File

@ -22,6 +22,11 @@ The following is a list of deprecated interfaces.
- Removed
- Alternatives
* - ``sphinx.ext.intersphinx.normalize_intersphinx_mapping``
- 8.0
- 10.0
- ``sphinx.ext.intersphinx.validate_intersphinx_mapping``
* - ``sphinx.testing.util.strip_escseq``
- 7.3
- 9.0

View File

@ -23,7 +23,7 @@ __all__ = (
'fetch_inventory',
'fetch_inventory_group',
'load_mappings',
'normalize_intersphinx_mapping',
'validate_intersphinx_mapping',
'IntersphinxRoleResolver',
'inventory_exists',
'install_dispatcher',
@ -44,7 +44,7 @@ from sphinx.ext.intersphinx._load import (
fetch_inventory,
fetch_inventory_group,
load_mappings,
normalize_intersphinx_mapping,
validate_intersphinx_mapping,
)
from sphinx.ext.intersphinx._resolve import (
IntersphinxDispatcher,
@ -69,7 +69,7 @@ def setup(app: Sphinx) -> ExtensionMetadata:
app.add_config_value('intersphinx_cache_limit', 5, '')
app.add_config_value('intersphinx_timeout', None, '')
app.add_config_value('intersphinx_disabled_reftypes', ['std:doc'], 'env')
app.connect('config-inited', normalize_intersphinx_mapping, priority=800)
app.connect('config-inited', validate_intersphinx_mapping, priority=800)
app.connect('builder-inited', load_mappings)
app.connect('source-read', install_dispatcher)
app.connect('missing-reference', missing_reference)
@ -79,3 +79,25 @@ def setup(app: Sphinx) -> ExtensionMetadata:
'env_version': 1,
'parallel_read_safe': True,
}
# deprecated name -> (object to return, canonical path or empty string, removal version)
_DEPRECATED_OBJECTS: dict[str, tuple[object, str, tuple[int, int]]] = {
'normalize_intersphinx_mapping': (
validate_intersphinx_mapping,
'sphinx.ext.intersphinx.validate_intersphinx_mapping',
(10, 0),
),
}
def __getattr__(name: str) -> object:
if name not in _DEPRECATED_OBJECTS:
msg = f'module {__name__!r} has no attribute {name!r}'
raise AttributeError(msg)
from sphinx.deprecation import _deprecation_warning
deprecated_object, canonical_name, remove = _DEPRECATED_OBJECTS[name]
_deprecation_warning(__name__, name, canonical_name, remove=remove)
return deprecated_object

View File

@ -32,7 +32,18 @@ if TYPE_CHECKING:
from sphinx.util.typing import Inventory
def normalize_intersphinx_mapping(app: Sphinx, config: Config) -> None:
def validate_intersphinx_mapping(app: Sphinx, config: Config) -> None:
"""Validate and normalise :confval:`intersphinx_mapping`.
Ensure that:
* Keys are non-empty strings.
* Values are two-element tuples or lists.
* The first element of each value pair (the target URI)
is a non-empty string.
* The second element of each value pair (inventory locations)
is a tuple of non-empty strings or None.
"""
# URIs should NOT be duplicated, otherwise different builds may use
# different project names (and thus, the build are no more reproducible)
# depending on which one is inserted last in the cache.

View File

@ -13,7 +13,7 @@ import pytest
from sphinx.builders.latex import default_latex_documents
from sphinx.config import Config
from sphinx.errors import SphinxError
from sphinx.ext.intersphinx import load_mappings, normalize_intersphinx_mapping
from sphinx.ext.intersphinx import load_mappings, validate_intersphinx_mapping
from sphinx.ext.intersphinx import setup as intersphinx_setup
from sphinx.util.osutil import ensuredir
from sphinx.writers.latex import LaTeXTranslator
@ -133,7 +133,7 @@ def test_build_latex_doc(app, engine, docclass, python_maximum_signature_line_le
app.config.latex_table_style = ['booktabs']
elif engine == 'lualatex':
app.config.latex_table_style = ['colorrows']
normalize_intersphinx_mapping(app, app.config)
validate_intersphinx_mapping(app, app.config)
load_mappings(app)
app.builder.init()
LaTeXTranslator.ignore_missing_images = True

View File

@ -22,7 +22,7 @@ from sphinx.addnodes import (
from sphinx.domains.c._ids import _id_prefix, _macroKeywords, _max_id
from sphinx.domains.c._parser import DefinitionParser
from sphinx.domains.c._symbol import Symbol
from sphinx.ext.intersphinx import load_mappings, normalize_intersphinx_mapping
from sphinx.ext.intersphinx import load_mappings, validate_intersphinx_mapping
from sphinx.testing import restructuredtext
from sphinx.testing.util import assert_node
from sphinx.util.cfamily import DefinitionError
@ -775,7 +775,7 @@ _var c:member 1 index.html#c.$ -
}
app.config.intersphinx_cache_limit = 0
# load the inventory and check if it's done correctly
normalize_intersphinx_mapping(app, app.config)
validate_intersphinx_mapping(app, app.config)
load_mappings(app)
app.build(force_all=True)

View File

@ -23,7 +23,7 @@ from sphinx.addnodes import (
from sphinx.domains.cpp._ids import _id_prefix, _max_id
from sphinx.domains.cpp._parser import DefinitionParser
from sphinx.domains.cpp._symbol import Symbol
from sphinx.ext.intersphinx import load_mappings, normalize_intersphinx_mapping
from sphinx.ext.intersphinx import load_mappings, validate_intersphinx_mapping
from sphinx.testing import restructuredtext
from sphinx.testing.util import assert_node
from sphinx.util.cfamily import DefinitionError, NoOldIdError
@ -1428,7 +1428,7 @@ _var cpp:member 1 index.html#_CPPv44$ -
}
app.config.intersphinx_cache_limit = 0
# load the inventory and check if it's done correctly
normalize_intersphinx_mapping(app, app.config)
validate_intersphinx_mapping(app, app.config)
load_mappings(app)
app.build(force_all=True)

View File

@ -12,7 +12,7 @@ from sphinx.ext.inheritance_diagram import (
InheritanceException,
import_classes,
)
from sphinx.ext.intersphinx import load_mappings, normalize_intersphinx_mapping
from sphinx.ext.intersphinx import load_mappings, validate_intersphinx_mapping
@pytest.mark.sphinx(buildername="html", testroot="inheritance")
@ -157,7 +157,7 @@ def test_inheritance_diagram_png_html(tmp_path, app):
'example': ('https://example.org', str(inv_file)),
}
app.config.intersphinx_cache_limit = 0
normalize_intersphinx_mapping(app, app.config)
validate_intersphinx_mapping(app, app.config)
load_mappings(app)
app.build(force_all=True)
@ -204,7 +204,7 @@ def test_inheritance_diagram_svg_html(tmp_path, app):
"subdir": ('https://example.org', str(inv_file)),
}
app.config.intersphinx_cache_limit = 0
normalize_intersphinx_mapping(app, app.config)
validate_intersphinx_mapping(app, app.config)
load_mappings(app)
app.build(force_all=True)

View File

@ -17,7 +17,7 @@ from sphinx.ext.intersphinx import (
inspect_main,
load_mappings,
missing_reference,
normalize_intersphinx_mapping,
validate_intersphinx_mapping,
)
from sphinx.ext.intersphinx import setup as intersphinx_setup
from sphinx.ext.intersphinx._load import _get_safe_url, _strip_basic_auth
@ -117,7 +117,7 @@ def test_missing_reference(tmp_path, app, status, warning):
})
# load the inventory and check if it's done correctly
normalize_intersphinx_mapping(app, app.config)
validate_intersphinx_mapping(app, app.config)
load_mappings(app)
inv = app.env.intersphinx_inventory
@ -192,7 +192,7 @@ def test_missing_reference_pydomain(tmp_path, app, status, warning):
})
# load the inventory and check if it's done correctly
normalize_intersphinx_mapping(app, app.config)
validate_intersphinx_mapping(app, app.config)
load_mappings(app)
# no context data
@ -222,7 +222,7 @@ def test_missing_reference_stddomain(tmp_path, app, status, warning):
})
# load the inventory and check if it's done correctly
normalize_intersphinx_mapping(app, app.config)
validate_intersphinx_mapping(app, app.config)
load_mappings(app)
# no context data
@ -272,7 +272,7 @@ def test_ambiguous_reference_warning(tmp_path, app, warning):
})
# load the inventory
normalize_intersphinx_mapping(app, app.config)
validate_intersphinx_mapping(app, app.config)
load_mappings(app)
# term reference (case insensitive)
@ -291,7 +291,7 @@ def test_missing_reference_cppdomain(tmp_path, app, status, warning):
})
# load the inventory and check if it's done correctly
normalize_intersphinx_mapping(app, app.config)
validate_intersphinx_mapping(app, app.config)
load_mappings(app)
app.build()
@ -317,7 +317,7 @@ def test_missing_reference_jsdomain(tmp_path, app, status, warning):
})
# load the inventory and check if it's done correctly
normalize_intersphinx_mapping(app, app.config)
validate_intersphinx_mapping(app, app.config)
load_mappings(app)
# no context data
@ -341,7 +341,7 @@ def test_missing_reference_disabled_domain(tmp_path, app, status, warning):
})
# load the inventory and check if it's done correctly
normalize_intersphinx_mapping(app, app.config)
validate_intersphinx_mapping(app, app.config)
load_mappings(app)
def case(*, term, doc, py):
@ -403,7 +403,7 @@ def test_inventory_not_having_version(tmp_path, app, status, warning):
})
# load the inventory and check if it's done correctly
normalize_intersphinx_mapping(app, app.config)
validate_intersphinx_mapping(app, app.config)
load_mappings(app)
rn = reference_check(app, 'py', 'mod', 'module1', 'foo')
@ -413,8 +413,8 @@ def test_inventory_not_having_version(tmp_path, app, status, warning):
assert rn[0].astext() == 'Long Module desc'
def test_normalize_intersphinx_mapping_warnings(app, warning):
"""Check warnings in :func:`sphinx.ext.intersphinx.normalize_intersphinx_mapping`."""
def test_validate_intersphinx_mapping_warnings(app, warning):
"""Check warnings in :func:`sphinx.ext.intersphinx.validate_intersphinx_mapping`."""
bad_intersphinx_mapping = {
# fmt: off
'': ('789.example', None), # invalid project name (value)
@ -445,7 +445,7 @@ def test_normalize_intersphinx_mapping_warnings(app, warning):
ConfigError,
match=r'^Invalid `intersphinx_mapping` configuration \(16 errors\).$',
):
normalize_intersphinx_mapping(app, app.config)
validate_intersphinx_mapping(app, app.config)
warnings = strip_colors(warning.getvalue()).splitlines()
assert len(warnings) == len(bad_intersphinx_mapping) - 3
assert warnings == [
@ -477,7 +477,7 @@ def test_load_mappings_fallback(tmp_path, app, status, warning):
app.config.intersphinx_mapping = {
'fallback': ('https://docs.python.org/py3k/', '/invalid/inventory/path'),
}
normalize_intersphinx_mapping(app, app.config)
validate_intersphinx_mapping(app, app.config)
load_mappings(app)
assert "failed to reach any of the inventories" in warning.getvalue()
@ -493,7 +493,7 @@ def test_load_mappings_fallback(tmp_path, app, status, warning):
'fallback': ('https://docs.python.org/py3k/', ('/invalid/inventory/path',
str(inv_file))),
}
normalize_intersphinx_mapping(app, app.config)
validate_intersphinx_mapping(app, app.config)
load_mappings(app)
assert "encountered some issues with some of the inventories" in status.getvalue()
assert warning.getvalue() == ""
@ -610,7 +610,7 @@ def test_intersphinx_role(app, warning):
app.config.nitpicky = True
# load the inventory and check if it's done correctly
normalize_intersphinx_mapping(app, app.config)
validate_intersphinx_mapping(app, app.config)
load_mappings(app)
app.build()

View File

@ -10,7 +10,7 @@ from unittest import mock
import pytest
from sphinx.ext.intersphinx import load_mappings, normalize_intersphinx_mapping
from sphinx.ext.intersphinx import load_mappings, validate_intersphinx_mapping
from sphinx.ext.napoleon import Config
from sphinx.ext.napoleon.docstring import (
GoogleDocstring,
@ -2679,7 +2679,7 @@ list py:class 1 list.html -
int py:class 1 int.html -
''')) # NoQA: W291
app.config.intersphinx_mapping = {'python': ('127.0.0.1:5555', str(inv_file))}
normalize_intersphinx_mapping(app, app.config)
validate_intersphinx_mapping(app, app.config)
load_mappings(app)
app.build(force_all=True)