summaryrefslogtreecommitdiffstats
path: root/tests/test_extensions
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test_extensions')
-rw-r--r--tests/test_extensions/test_ext_apidoc.py25
-rw-r--r--tests/test_extensions/test_ext_autodoc.py54
-rw-r--r--tests/test_extensions/test_ext_autodoc_automodule.py16
-rw-r--r--tests/test_extensions/test_ext_autodoc_configs.py31
-rw-r--r--tests/test_extensions/test_ext_autosummary.py38
-rw-r--r--tests/test_extensions/test_ext_autosummary_imports.py49
-rw-r--r--tests/test_extensions/test_ext_coverage.py40
-rw-r--r--tests/test_extensions/test_ext_graphviz.py2
-rw-r--r--tests/test_extensions/test_ext_imgconverter.py4
-rw-r--r--tests/test_extensions/test_ext_imgmockconverter.py2
-rw-r--r--tests/test_extensions/test_ext_inheritance_diagram.py2
-rw-r--r--tests/test_extensions/test_ext_intersphinx.py33
-rw-r--r--tests/test_extensions/test_ext_math.py22
-rw-r--r--tests/test_extensions/test_ext_todo.py2
-rw-r--r--tests/test_extensions/test_ext_viewcode.py4
15 files changed, 272 insertions, 52 deletions
diff --git a/tests/test_extensions/test_ext_apidoc.py b/tests/test_extensions/test_ext_apidoc.py
index c3c979f..13c43df 100644
--- a/tests/test_extensions/test_ext_apidoc.py
+++ b/tests/test_extensions/test_ext_apidoc.py
@@ -2,6 +2,7 @@
import os.path
from collections import namedtuple
+from pathlib import Path
import pytest
@@ -9,7 +10,7 @@ import sphinx.ext.apidoc
from sphinx.ext.apidoc import main as apidoc_main
-@pytest.fixture()
+@pytest.fixture
def apidoc(rootdir, tmp_path, apidoc_params):
_, kwargs = apidoc_params
coderoot = rootdir / kwargs.get('coderoot', 'test-root')
@@ -20,7 +21,7 @@ def apidoc(rootdir, tmp_path, apidoc_params):
return namedtuple('apidoc', 'coderoot,outdir')(coderoot, outdir)
-@pytest.fixture()
+@pytest.fixture
def apidoc_params(request):
pargs = {}
kwargs = {}
@@ -661,3 +662,23 @@ def test_no_duplicates(rootdir, tmp_path):
finally:
sphinx.ext.apidoc.PY_SUFFIXES = original_suffixes
+
+
+def test_remove_old_files(tmp_path: Path):
+ """Test that old files are removed when using the -r option.
+
+ Also ensure that pre-existing files are not re-written, if unchanged.
+ This is required to avoid unnecessary rebuilds.
+ """
+ module_dir = tmp_path / 'module'
+ module_dir.mkdir()
+ (module_dir / 'example.py').write_text('', encoding='utf8')
+ gen_dir = tmp_path / 'gen'
+ gen_dir.mkdir()
+ (gen_dir / 'other.rst').write_text('', encoding='utf8')
+ apidoc_main(['-o', str(gen_dir), str(module_dir)])
+ assert set(gen_dir.iterdir()) == {gen_dir / 'modules.rst', gen_dir / 'example.rst', gen_dir / 'other.rst'}
+ example_mtime = (gen_dir / 'example.rst').stat().st_mtime
+ apidoc_main(['--remove-old', '-o', str(gen_dir), str(module_dir)])
+ assert set(gen_dir.iterdir()) == {gen_dir / 'modules.rst', gen_dir / 'example.rst'}
+ assert (gen_dir / 'example.rst').stat().st_mtime == example_mtime
diff --git a/tests/test_extensions/test_ext_autodoc.py b/tests/test_extensions/test_ext_autodoc.py
index 54f81f2..e10850b 100644
--- a/tests/test_extensions/test_ext_autodoc.py
+++ b/tests/test_extensions/test_ext_autodoc.py
@@ -429,7 +429,7 @@ def _assert_getter_works(app, directive, objtype, name, attrs=(), **kw):
hooked_members = {s[1] for s in getattr_spy}
documented_members = {s[1] for s in processed_signatures}
for attr in attrs:
- fullname = '.'.join((name, attr))
+ fullname = f'{name}.{attr}'
assert attr in hooked_members
assert fullname not in documented_members, f'{fullname!r} not intercepted'
@@ -838,7 +838,7 @@ def test_autodoc_special_members(app):
"special-members": None,
}
if sys.version_info >= (3, 13, 0, 'alpha', 5):
- options["exclude-members"] = "__static_attributes__"
+ options["exclude-members"] = "__static_attributes__,__firstlineno__"
actual = do_autodoc(app, 'class', 'target.Class', options)
assert list(filter(lambda l: '::' in l, actual)) == [
'.. py:class:: Class(arg)',
@@ -1479,7 +1479,7 @@ class _EnumFormatter:
return self.entry(name, doc, role='attribute', indent=indent, **rst_options)
-@pytest.fixture()
+@pytest.fixture
def autodoc_enum_options() -> dict[str, object]:
"""Default autodoc options to use when testing enum's documentation."""
return {"members": None, "undoc-members": None}
@@ -2321,18 +2321,62 @@ def test_autodoc_TypeVar(app):
@pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_autodoc_Annotated(app):
- options = {"members": None}
+ options = {'members': None, 'member-order': 'bysource'}
actual = do_autodoc(app, 'module', 'target.annotated', options)
assert list(actual) == [
'',
'.. py:module:: target.annotated',
'',
'',
- '.. py:function:: hello(name: str) -> None',
+ '.. py:class:: FuncValidator(func: function)',
+ ' :module: target.annotated',
+ '',
+ '',
+ '.. py:class:: MaxLen(max_length: int, whitelisted_words: list[str])',
+ ' :module: target.annotated',
+ '',
+ '',
+ '.. py:data:: ValidatedString',
+ ' :module: target.annotated',
+ '',
+ ' Type alias for a validated string.',
+ '',
+ ' alias of :py:class:`~typing.Annotated`\\ [:py:class:`str`, '
+ ':py:class:`~target.annotated.FuncValidator`\\ (func=\\ :py:class:`~target.annotated.validate`)]',
+ '',
+ '',
+ ".. py:function:: hello(name: ~typing.Annotated[str, 'attribute']) -> None",
+ ' :module: target.annotated',
+ '',
+ ' docstring',
+ '',
+ '',
+ '.. py:class:: AnnotatedAttributes()',
' :module: target.annotated',
'',
' docstring',
'',
+ '',
+ ' .. py:attribute:: AnnotatedAttributes.name',
+ ' :module: target.annotated',
+ " :type: ~typing.Annotated[str, 'attribute']",
+ '',
+ ' Docstring about the ``name`` attribute.',
+ '',
+ '',
+ ' .. py:attribute:: AnnotatedAttributes.max_len',
+ ' :module: target.annotated',
+ " :type: list[~typing.Annotated[str, ~target.annotated.MaxLen(max_length=10, whitelisted_words=['word_one', 'word_two'])]]",
+ '',
+ ' Docstring about the ``max_len`` attribute.',
+ '',
+ '',
+ ' .. py:attribute:: AnnotatedAttributes.validated',
+ ' :module: target.annotated',
+ ' :type: ~typing.Annotated[str, ~target.annotated.FuncValidator(func=~target.annotated.validate)]',
+ '',
+ ' Docstring about the ``validated`` attribute.',
+ '',
]
diff --git a/tests/test_extensions/test_ext_autodoc_automodule.py b/tests/test_extensions/test_ext_autodoc_automodule.py
index 92565ae..c6ced7e 100644
--- a/tests/test_extensions/test_ext_autodoc_automodule.py
+++ b/tests/test_extensions/test_ext_autodoc_automodule.py
@@ -4,7 +4,9 @@ This tests mainly the Documenters; the auto directives are tested in a test
source file translated by test_build.
"""
+import inspect
import sys
+import typing
import pytest
@@ -185,8 +187,22 @@ def test_automodule_inherited_members(app):
'sphinx.missing_module4']})
@pytest.mark.usefixtures("rollback_sysmodules")
def test_subclass_of_mocked_object(app):
+ from sphinx.ext.autodoc.mock import _MockObject
sys.modules.pop('target', None) # unload target module to clear the module cache
options = {'members': None}
actual = do_autodoc(app, 'module', 'target.need_mocks', options)
+ # ``typing.Any`` is not available at runtime on ``_MockObject.__new__``
+ assert '.. py:class:: Inherited(*args: Any, **kwargs: Any)' in actual
+
+ # make ``typing.Any`` available at runtime on ``_MockObject.__new__``
+ sig = inspect.signature(_MockObject.__new__)
+ parameters = sig.parameters.copy()
+ for name in ('args', 'kwargs'):
+ parameters[name] = parameters[name].replace(annotation=typing.Any)
+ sig = sig.replace(parameters=tuple(parameters.values()))
+ _MockObject.__new__.__signature__ = sig # type: ignore[attr-defined]
+
+ options = {'members': None}
+ actual = do_autodoc(app, 'module', 'target.need_mocks', options)
assert '.. py:class:: Inherited(*args: ~typing.Any, **kwargs: ~typing.Any)' in actual
diff --git a/tests/test_extensions/test_ext_autodoc_configs.py b/tests/test_extensions/test_ext_autodoc_configs.py
index 6c2af5a..1262b15 100644
--- a/tests/test_extensions/test_ext_autodoc_configs.py
+++ b/tests/test_extensions/test_ext_autodoc_configs.py
@@ -679,6 +679,10 @@ def test_autodoc_typehints_signature(app):
type_o = "~typing.Any | None"
else:
type_o = "~typing.Any"
+ if sys.version_info[:2] >= (3, 13):
+ type_ppp = "pathlib._local.PurePosixPath"
+ else:
+ type_ppp = "pathlib.PurePosixPath"
options = {"members": None,
"undoc-members": None}
@@ -703,7 +707,7 @@ def test_autodoc_typehints_signature(app):
'',
'.. py:data:: CONST3',
' :module: target.typehints',
- ' :type: ~pathlib.PurePosixPath',
+ f' :type: ~{type_ppp}',
" :value: PurePosixPath('/a/b/c')",
'',
' docstring',
@@ -726,7 +730,7 @@ def test_autodoc_typehints_signature(app):
'',
' .. py:attribute:: Math.CONST3',
' :module: target.typehints',
- ' :type: ~pathlib.PurePosixPath',
+ f' :type: ~{type_ppp}',
" :value: PurePosixPath('/a/b/c')",
'',
'',
@@ -748,7 +752,7 @@ def test_autodoc_typehints_signature(app):
'',
' .. py:property:: Math.path',
' :module: target.typehints',
- ' :type: ~pathlib.PurePosixPath',
+ f' :type: ~{type_ppp}',
'',
'',
' .. py:property:: Math.prop',
@@ -773,7 +777,7 @@ def test_autodoc_typehints_signature(app):
'',
' docstring',
'',
- " alias of TypeVar('T', bound=\\ :py:class:`~pathlib.PurePosixPath`)",
+ f" alias of TypeVar('T', bound=\\ :py:class:`~{type_ppp}`)",
'',
'',
'.. py:function:: complex_func(arg1: str, arg2: List[int], arg3: Tuple[int, '
@@ -802,6 +806,10 @@ def test_autodoc_typehints_signature(app):
@pytest.mark.sphinx('html', testroot='ext-autodoc',
confoverrides={'autodoc_typehints': "none"})
def test_autodoc_typehints_none(app):
+ if sys.version_info[:2] >= (3, 13):
+ type_ppp = "pathlib._local.PurePosixPath"
+ else:
+ type_ppp = "pathlib.PurePosixPath"
options = {"members": None,
"undoc-members": None}
actual = do_autodoc(app, 'module', 'target.typehints', options)
@@ -887,7 +895,7 @@ def test_autodoc_typehints_none(app):
'',
' docstring',
'',
- " alias of TypeVar('T', bound=\\ :py:class:`~pathlib.PurePosixPath`)",
+ f" alias of TypeVar('T', bound=\\ :py:class:`~{type_ppp}`)",
'',
'',
'.. py:function:: complex_func(arg1, arg2, arg3=None, *args, **kwargs)',
@@ -1417,7 +1425,10 @@ def test_autodoc_typehints_format_fully_qualified(app):
type_o = "typing.Any | None"
else:
type_o = "typing.Any"
-
+ if sys.version_info[:2] >= (3, 13):
+ type_ppp = "pathlib._local.PurePosixPath"
+ else:
+ type_ppp = "pathlib.PurePosixPath"
options = {"members": None,
"undoc-members": None}
actual = do_autodoc(app, 'module', 'target.typehints', options)
@@ -1441,7 +1452,7 @@ def test_autodoc_typehints_format_fully_qualified(app):
'',
'.. py:data:: CONST3',
' :module: target.typehints',
- ' :type: pathlib.PurePosixPath',
+ f' :type: {type_ppp}',
" :value: PurePosixPath('/a/b/c')",
'',
' docstring',
@@ -1464,7 +1475,7 @@ def test_autodoc_typehints_format_fully_qualified(app):
'',
' .. py:attribute:: Math.CONST3',
' :module: target.typehints',
- ' :type: pathlib.PurePosixPath',
+ f' :type: {type_ppp}',
" :value: PurePosixPath('/a/b/c')",
'',
'',
@@ -1486,7 +1497,7 @@ def test_autodoc_typehints_format_fully_qualified(app):
'',
' .. py:property:: Math.path',
' :module: target.typehints',
- ' :type: pathlib.PurePosixPath',
+ f' :type: {type_ppp}',
'',
'',
' .. py:property:: Math.prop',
@@ -1511,7 +1522,7 @@ def test_autodoc_typehints_format_fully_qualified(app):
'',
' docstring',
'',
- " alias of TypeVar('T', bound=\\ :py:class:`pathlib.PurePosixPath`)",
+ f" alias of TypeVar('T', bound=\\ :py:class:`{type_ppp}`)",
'',
'',
'.. py:function:: complex_func(arg1: str, arg2: List[int], arg3: Tuple[int, '
diff --git a/tests/test_extensions/test_ext_autosummary.py b/tests/test_extensions/test_ext_autosummary.py
index d761978..e3f034c 100644
--- a/tests/test_extensions/test_ext_autosummary.py
+++ b/tests/test_extensions/test_ext_autosummary.py
@@ -506,12 +506,20 @@ def test_autosummary_recursive(app, status, warning):
# Check content of recursively generated stub-files
content = (app.srcdir / 'generated' / 'package.rst').read_text(encoding='utf8')
- assert 'package.module' in content
- assert 'package.package' in content
- assert 'package.module_importfail' in content
+ assert 'module' in content
+ assert 'package' in content
+ assert 'module_importfail' in content
+ # we no longer generate fully-qualified module names.
+ assert 'package.module' not in content
+ assert 'package.package' not in content
+ assert 'package.module_importfail' not in content
content = (app.srcdir / 'generated' / 'package.package.rst').read_text(encoding='utf8')
- assert 'package.package.module' in content
+ assert 'module' in content
+ assert 'package.package.module' not in content
+
+ warnings = app.warning.getvalue()
+ assert 'Summarised items should not include the current module.' not in warnings
@pytest.mark.sphinx('dummy', testroot='ext-autosummary-recursive',
@@ -545,7 +553,7 @@ def test_autosummary_filename_map(app, status, warning):
@pytest.mark.sphinx('latex', **default_kw)
def test_autosummary_latex_table_colspec(app, status, warning):
app.build(force_all=True)
- result = (app.outdir / 'python.tex').read_text(encoding='utf8')
+ result = (app.outdir / 'projectnamenotset.tex').read_text(encoding='utf8')
print(status.getvalue())
print(warning.getvalue())
assert r'\begin{longtable}{\X{1}{2}\X{1}{2}}' in result
@@ -599,11 +607,11 @@ def test_autosummary_imported_members(app, status, warning):
assert (' .. autosummary::\n'
' \n'
' Bar\n'
- ' \n' in module)
+ ' ' in module)
assert (' .. autosummary::\n'
' \n'
' foo\n'
- ' \n' in module)
+ ' ' in module)
finally:
sys.modules.pop('autosummary_dummy_package', None)
@@ -627,7 +635,7 @@ def test_autosummary_module_all(app, status, warning):
assert ('.. autosummary::\n'
' :toctree:\n'
' :recursive:\n\n'
- ' autosummary_dummy_package_all.extra_dummy_module\n\n' in module)
+ ' extra_dummy_module\n' in module)
finally:
sys.modules.pop('autosummary_dummy_package_all', None)
@@ -684,3 +692,17 @@ def test_autogen(rootdir, tmp_path):
args = ['-o', str(tmp_path), '-t', '.', 'autosummary_templating.txt']
autogen_main(args)
assert (tmp_path / 'sphinx.application.TemplateBridge.rst').exists()
+
+
+def test_autogen_remove_old(rootdir, tmp_path):
+ """Test the ``--remove-old`` option."""
+ tmp_path.joinpath('other.rst').write_text('old content')
+ with chdir(rootdir / 'test-templating'):
+ args = ['-o', str(tmp_path), '-t', '.', 'autosummary_templating.txt']
+ autogen_main(args)
+ assert set(tmp_path.iterdir()) == {
+ tmp_path / 'sphinx.application.TemplateBridge.rst',
+ tmp_path / 'other.rst'
+ }
+ autogen_main([*args, '--remove-old'])
+ assert set(tmp_path.iterdir()) == {tmp_path / 'sphinx.application.TemplateBridge.rst'}
diff --git a/tests/test_extensions/test_ext_autosummary_imports.py b/tests/test_extensions/test_ext_autosummary_imports.py
new file mode 100644
index 0000000..7420c99
--- /dev/null
+++ b/tests/test_extensions/test_ext_autosummary_imports.py
@@ -0,0 +1,49 @@
+"""Test autosummary for import cycles."""
+
+import pytest
+from docutils import nodes
+
+from sphinx import addnodes
+from sphinx.ext.autosummary import autosummary_table
+from sphinx.testing.util import assert_node
+
+
+@pytest.mark.sphinx('dummy', testroot='ext-autosummary-import_cycle')
+@pytest.mark.usefixtures("rollback_sysmodules")
+def test_autosummary_import_cycle(app, warning):
+ app.build()
+
+ doctree = app.env.get_doctree('index')
+ app.env.apply_post_transforms(doctree, 'index')
+
+ assert len(list(doctree.findall(nodes.reference))) == 1
+
+ assert_node(doctree,
+ (addnodes.index, # [0]
+ nodes.target, # [1]
+ nodes.paragraph, # [2]
+ addnodes.tabular_col_spec, # [3]
+ [autosummary_table, nodes.table, nodes.tgroup, (nodes.colspec, # [4][0][0][0]
+ nodes.colspec, # [4][0][0][1]
+ [nodes.tbody, nodes.row])], # [4][0][0][2][1]
+ addnodes.index, # [5]
+ addnodes.desc)) # [6]
+ assert_node(doctree[4][0][0][2][0],
+ ([nodes.entry, nodes.paragraph, (nodes.reference, nodes.Text)], nodes.entry))
+ assert_node(doctree[4][0][0][2][0][0][0][0], nodes.reference,
+ refid='spam.eggs.Ham', reftitle='spam.eggs.Ham')
+
+ expected = (
+ "Summarised items should not include the current module. "
+ "Replace 'spam.eggs.Ham' with 'Ham'."
+ )
+ assert expected in app.warning.getvalue()
+
+
+@pytest.mark.sphinx('dummy', testroot='ext-autosummary-module_prefix')
+@pytest.mark.usefixtures("rollback_sysmodules")
+def test_autosummary_generate_prefixes(app, warning):
+ app.build()
+ warnings = app.warning.getvalue()
+ assert 'Summarised items should not include the current module.' not in warnings
+ assert warnings == ''
diff --git a/tests/test_extensions/test_ext_coverage.py b/tests/test_extensions/test_ext_coverage.py
index c9e9ba9..ed7b5ad 100644
--- a/tests/test_extensions/test_ext_coverage.py
+++ b/tests/test_extensions/test_ext_coverage.py
@@ -10,8 +10,10 @@ def test_build(app, status, warning):
app.build(force_all=True)
py_undoc = (app.outdir / 'python.txt').read_text(encoding='utf8')
- assert py_undoc.startswith('Undocumented Python objects\n'
- '===========================\n')
+ assert py_undoc.startswith(
+ 'Undocumented Python objects\n'
+ '===========================\n',
+ )
assert 'autodoc_target\n--------------\n' in py_undoc
assert ' * Class -- missing methods:\n' in py_undoc
assert ' * raises\n' in py_undoc
@@ -23,8 +25,10 @@ def test_build(app, status, warning):
assert "undocumented py" not in status.getvalue()
c_undoc = (app.outdir / 'c.txt').read_text(encoding='utf8')
- assert c_undoc.startswith('Undocumented C API elements\n'
- '===========================\n')
+ assert c_undoc.startswith(
+ 'Undocumented C API elements\n'
+ '===========================\n',
+ )
assert 'api.h' in c_undoc
assert ' * Py_SphinxTest' in c_undoc
@@ -54,16 +58,26 @@ Undocumented Python objects
Statistics
----------
-+----------------------+----------+--------------+
-| Module | Coverage | Undocumented |
-+======================+==========+==============+
-| coverage_not_ignored | 0.00% | 2 |
-+----------------------+----------+--------------+
-| TOTAL | 0.00% | 2 |
-+----------------------+----------+--------------+
++---------------------------+----------+--------------+
+| Module | Coverage | Undocumented |
++===========================+==========+==============+
+| grog | 100.00% | 0 |
++---------------------------+----------+--------------+
+| grog.coverage_missing | 100.00% | 0 |
++---------------------------+----------+--------------+
+| grog.coverage_not_ignored | 0.00% | 2 |
++---------------------------+----------+--------------+
+| TOTAL | 0.00% | 2 |
++---------------------------+----------+--------------+
+
+grog.coverage_missing
+---------------------
-coverage_not_ignored
---------------------
+Classes:
+ * Missing
+
+grog.coverage_not_ignored
+-------------------------
Classes:
* Documented -- missing methods:
diff --git a/tests/test_extensions/test_ext_graphviz.py b/tests/test_extensions/test_ext_graphviz.py
index 866a92a..cd1fd92 100644
--- a/tests/test_extensions/test_ext_graphviz.py
+++ b/tests/test_extensions/test_ext_graphviz.py
@@ -105,7 +105,7 @@ def test_graphviz_svg_html(app, status, warning):
def test_graphviz_latex(app, status, warning):
app.build(force_all=True)
- content = (app.outdir / 'python.tex').read_text(encoding='utf8')
+ content = (app.outdir / 'projectnamenotset.tex').read_text(encoding='utf8')
macro = ('\\\\begin{figure}\\[htbp\\]\n\\\\centering\n\\\\capstart\n\n'
'\\\\sphinxincludegraphics\\[\\]{graphviz-\\w+.pdf}\n'
'\\\\caption{caption of graph}\\\\label{.*}\\\\end{figure}')
diff --git a/tests/test_extensions/test_ext_imgconverter.py b/tests/test_extensions/test_ext_imgconverter.py
index c1d2061..fee6593 100644
--- a/tests/test_extensions/test_ext_imgconverter.py
+++ b/tests/test_extensions/test_ext_imgconverter.py
@@ -5,7 +5,7 @@ import subprocess
import pytest
-@pytest.fixture()
+@pytest.fixture
def _if_converter_found(app):
image_converter = getattr(app.config, 'image_converter', '')
try:
@@ -24,7 +24,7 @@ def _if_converter_found(app):
def test_ext_imgconverter(app, status, warning):
app.build(force_all=True)
- content = (app.outdir / 'python.tex').read_text(encoding='utf8')
+ content = (app.outdir / 'projectnamenotset.tex').read_text(encoding='utf8')
# supported image (not converted)
assert '\\sphinxincludegraphics{{img}.pdf}' in content
diff --git a/tests/test_extensions/test_ext_imgmockconverter.py b/tests/test_extensions/test_ext_imgmockconverter.py
index 4c3c64e..c155274 100644
--- a/tests/test_extensions/test_ext_imgmockconverter.py
+++ b/tests/test_extensions/test_ext_imgmockconverter.py
@@ -7,7 +7,7 @@ import pytest
def test_ext_imgmockconverter(app, status, warning):
app.build(force_all=True)
- content = (app.outdir / 'python.tex').read_text(encoding='utf8')
+ content = (app.outdir / 'projectnamenotset.tex').read_text(encoding='utf8')
# check identical basenames give distinct files
assert '\\sphinxincludegraphics{{svgimg}.pdf}' in content
diff --git a/tests/test_extensions/test_ext_inheritance_diagram.py b/tests/test_extensions/test_ext_inheritance_diagram.py
index c13ccea..45a5ff0 100644
--- a/tests/test_extensions/test_ext_inheritance_diagram.py
+++ b/tests/test_extensions/test_ext_inheritance_diagram.py
@@ -251,7 +251,7 @@ def test_inheritance_diagram_svg_html(tmp_path, app):
def test_inheritance_diagram_latex(app, status, warning):
app.build(force_all=True)
- content = (app.outdir / 'python.tex').read_text(encoding='utf8')
+ content = (app.outdir / 'projectnamenotset.tex').read_text(encoding='utf8')
pattern = ('\\\\begin{figure}\\[htbp]\n\\\\centering\n\\\\capstart\n\n'
'\\\\sphinxincludegraphics\\[\\]{inheritance-\\w+.pdf}\n'
diff --git a/tests/test_extensions/test_ext_intersphinx.py b/tests/test_extensions/test_ext_intersphinx.py
index ef5a9b1..d475c60 100644
--- a/tests/test_extensions/test_ext_intersphinx.py
+++ b/tests/test_extensions/test_ext_intersphinx.py
@@ -7,10 +7,8 @@ import pytest
from docutils import nodes
from sphinx import addnodes
+from sphinx.builders.html import INVENTORY_FILENAME
from sphinx.ext.intersphinx import (
- INVENTORY_FILENAME,
- _get_safe_url,
- _strip_basic_auth,
fetch_inventory,
inspect_main,
load_mappings,
@@ -18,9 +16,14 @@ from sphinx.ext.intersphinx import (
normalize_intersphinx_mapping,
)
from sphinx.ext.intersphinx import setup as intersphinx_setup
+from sphinx.ext.intersphinx._load import _get_safe_url, _strip_basic_auth
from sphinx.util.console import strip_colors
-from tests.test_util.intersphinx_data import INVENTORY_V2, INVENTORY_V2_NO_VERSION
+from tests.test_util.intersphinx_data import (
+ INVENTORY_V2,
+ INVENTORY_V2_AMBIGUOUS_TERMS,
+ INVENTORY_V2_NO_VERSION,
+)
from tests.utils import http_server
@@ -46,8 +49,8 @@ def set_config(app, mapping):
app.config.intersphinx_disabled_reftypes = []
-@mock.patch('sphinx.ext.intersphinx.InventoryFile')
-@mock.patch('sphinx.ext.intersphinx._read_from_url')
+@mock.patch('sphinx.ext.intersphinx._load.InventoryFile')
+@mock.patch('sphinx.ext.intersphinx._load._read_from_url')
def test_fetch_inventory_redirection(_read_from_url, InventoryFile, app, status, warning): # NoQA: PT019
intersphinx_setup(app)
_read_from_url().readline.return_value = b'# Sphinx inventory version 2'
@@ -248,6 +251,24 @@ def test_missing_reference_stddomain(tmp_path, app, status, warning):
assert rn.astext() == 'The Julia Domain'
+def test_ambiguous_reference_warning(tmp_path, app, warning):
+ inv_file = tmp_path / 'inventory'
+ inv_file.write_bytes(INVENTORY_V2_AMBIGUOUS_TERMS)
+ set_config(app, {
+ 'cmd': ('https://docs.python.org/', str(inv_file)),
+ })
+
+ # load the inventory
+ normalize_intersphinx_mapping(app, app.config)
+ load_mappings(app)
+
+ # term reference (case insensitive)
+ node, contnode = fake_node('std', 'term', 'A TERM', 'A TERM')
+ missing_reference(app, app.env, node, contnode)
+
+ assert 'multiple matches found for std:term:A TERM' in warning.getvalue()
+
+
@pytest.mark.sphinx('html', testroot='ext-intersphinx-cppdomain')
def test_missing_reference_cppdomain(tmp_path, app, status, warning):
inv_file = tmp_path / 'inventory'
diff --git a/tests/test_extensions/test_ext_math.py b/tests/test_extensions/test_ext_math.py
index b673f83..80a5ae7 100644
--- a/tests/test_extensions/test_ext_math.py
+++ b/tests/test_extensions/test_ext_math.py
@@ -127,7 +127,7 @@ def test_math_number_all_mathjax(app, status, warning):
def test_math_number_all_latex(app, status, warning):
app.build()
- content = (app.outdir / 'python.tex').read_text(encoding='utf8')
+ content = (app.outdir / 'projectnamenotset.tex').read_text(encoding='utf8')
macro = (r'\\begin{equation\*}\s*'
r'\\begin{split}a\^2\+b\^2=c\^2\\end{split}\s*'
r'\\end{equation\*}')
@@ -170,7 +170,7 @@ def test_math_eqref_format_html(app, status, warning):
def test_math_eqref_format_latex(app, status, warning):
app.build(force_all=True)
- content = (app.outdir / 'python.tex').read_text(encoding='utf8')
+ content = (app.outdir / 'projectnamenotset.tex').read_text(encoding='utf8')
macro = (r'Referencing equation Eq.\\ref{equation:math:foo} and '
r'Eq.\\ref{equation:math:foo}.')
assert re.search(macro, content, re.DOTALL)
@@ -194,6 +194,24 @@ def test_mathjax_numfig_html(app, status, warning):
@pytest.mark.sphinx('html', testroot='ext-math',
+ confoverrides={'extensions': ['sphinx.ext.mathjax'],
+ 'numfig': True,
+ 'math_numfig': True,
+ 'math_numsep': '-'})
+def test_mathjax_numsep_html(app, status, warning):
+ app.build(force_all=True)
+
+ content = (app.outdir / 'math.html').read_text(encoding='utf8')
+ html = ('<div class="math notranslate nohighlight" id="equation-math-0">\n'
+ '<span class="eqno">(1-2)')
+ assert html in content
+ html = ('<p>Referencing equation <a class="reference internal" '
+ 'href="#equation-foo">(1-1)</a> and '
+ '<a class="reference internal" href="#equation-foo">(1-1)</a>.</p>')
+ assert html in content
+
+
+@pytest.mark.sphinx('html', testroot='ext-math',
confoverrides={'extensions': ['sphinx.ext.imgmath'],
'numfig': True,
'numfig_secnum_depth': 0,
diff --git a/tests/test_extensions/test_ext_todo.py b/tests/test_extensions/test_ext_todo.py
index 1903f9f..5acfcac 100644
--- a/tests/test_extensions/test_ext_todo.py
+++ b/tests/test_extensions/test_ext_todo.py
@@ -89,7 +89,7 @@ def test_todo_valid_link(app, status, warning):
# Ensure the LaTeX output is built.
app.build(force_all=True)
- content = (app.outdir / 'python.tex').read_text(encoding='utf8')
+ content = (app.outdir / 'projectnamenotset.tex').read_text(encoding='utf8')
# Look for the link to foo. Note that there are two of them because the
# source document uses todolist twice. We could equally well look for links
diff --git a/tests/test_extensions/test_ext_viewcode.py b/tests/test_extensions/test_ext_viewcode.py
index b2c6fc0..800904a 100644
--- a/tests/test_extensions/test_ext_viewcode.py
+++ b/tests/test_extensions/test_ext_viewcode.py
@@ -42,6 +42,7 @@ def check_viewcode_output(app, warning):
@pytest.mark.sphinx(testroot='ext-viewcode', freshenv=True,
confoverrides={"viewcode_line_numbers": True})
+@pytest.mark.usefixtures("rollback_sysmodules")
def test_viewcode_linenos(app, warning):
shutil.rmtree(app.outdir / '_modules', ignore_errors=True)
app.build(force_all=True)
@@ -52,6 +53,7 @@ def test_viewcode_linenos(app, warning):
@pytest.mark.sphinx(testroot='ext-viewcode', freshenv=True,
confoverrides={"viewcode_line_numbers": False})
+@pytest.mark.usefixtures("rollback_sysmodules")
def test_viewcode(app, warning):
shutil.rmtree(app.outdir / '_modules', ignore_errors=True)
app.build(force_all=True)
@@ -61,6 +63,7 @@ def test_viewcode(app, warning):
@pytest.mark.sphinx('epub', testroot='ext-viewcode')
+@pytest.mark.usefixtures("rollback_sysmodules")
def test_viewcode_epub_default(app, status, warning):
shutil.rmtree(app.outdir)
app.build(force_all=True)
@@ -73,6 +76,7 @@ def test_viewcode_epub_default(app, status, warning):
@pytest.mark.sphinx('epub', testroot='ext-viewcode',
confoverrides={'viewcode_enable_epub': True})
+@pytest.mark.usefixtures("rollback_sysmodules")
def test_viewcode_epub_enabled(app, status, warning):
app.build(force_all=True)