mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2026-10-12 08:25:01 -05:00
Remove 'untyped_defs' mypy overrides (#14103)
This commit is contained in:
1 parent
227b230be8
commit
a82b34feea
13 files changed
+336
-177
No files matched your search
@@ -217,32 +217,6 @@ module = [
|
||||
]
|
||||
ignore_missing_imports = true
|
||||
|
||||
[[tool.mypy.overrides]]
|
||||
module = [
|
||||
# tests/
|
||||
"tests.test_versioning",
|
||||
# tests/test_builders
|
||||
"tests.test_builders.test_build",
|
||||
"tests.test_builders.test_build_html",
|
||||
"tests.test_builders.test_build_linkcheck",
|
||||
# tests/test_directives
|
||||
"tests.test_directives.test_directive_code",
|
||||
"tests.test_directives.test_directives_no_typesetting",
|
||||
# tests/test_ext_autodoc
|
||||
"tests.test_ext_autodoc.test_ext_autodoc_autoclass",
|
||||
# tests/test_ext_autosummary
|
||||
"tests.test_ext_autosummary.test_ext_autosummary_imports",
|
||||
# tests/test_ext_intersphinx
|
||||
"tests.test_ext_intersphinx.test_ext_intersphinx_cache",
|
||||
# tests/test_ext_napoleon
|
||||
"tests.test_ext_napoleon.test_ext_napoleon",
|
||||
# tests/test_extensions
|
||||
"tests.test_extensions.test_ext_math",
|
||||
# tests/test_theming
|
||||
"tests.test_theming.test_templating",
|
||||
]
|
||||
disallow_untyped_defs = false
|
||||
|
||||
[[tool.mypy.overrides]]
|
||||
module = [
|
||||
# tests/
|
||||
|
||||
@@ -10,10 +10,15 @@ from docutils import nodes
|
||||
from sphinx.errors import SphinxError
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from collections.abc import Callable
|
||||
from pathlib import Path
|
||||
|
||||
from sphinx.testing.util import SphinxTestApp
|
||||
|
||||
|
||||
def test_root_doc_not_found(tmp_path, make_app):
|
||||
def test_root_doc_not_found(
|
||||
tmp_path: Path, make_app: Callable[..., SphinxTestApp]
|
||||
) -> None:
|
||||
(tmp_path / 'conf.py').touch()
|
||||
assert [p.name for p in tmp_path.iterdir()] == ['conf.py']
|
||||
|
||||
@@ -56,11 +61,12 @@ def test_multiple_parents_toctree(app: SphinxTestApp) -> None:
|
||||
|
||||
@pytest.mark.usefixtures('_http_teapot')
|
||||
@pytest.mark.sphinx('dummy', testroot='images')
|
||||
def test_image_glob(app):
|
||||
def test_image_glob(app: SphinxTestApp) -> None:
|
||||
app.build(force_all=True)
|
||||
|
||||
# index.rst
|
||||
doctree = app.env.get_doctree('index')
|
||||
assert isinstance(doctree[0], nodes.Element)
|
||||
|
||||
assert isinstance(doctree[0][1], nodes.image)
|
||||
assert doctree[0][1]['candidates'] == {'*': 'rimg.png'}
|
||||
@@ -90,6 +96,7 @@ def test_image_glob(app):
|
||||
|
||||
# subdir/index.rst
|
||||
doctree = app.env.get_doctree('subdir/index')
|
||||
assert isinstance(doctree[0], nodes.Element)
|
||||
|
||||
assert isinstance(doctree[0][1], nodes.image)
|
||||
assert doctree[0][1]['candidates'] == {'*': 'subdir/rimg.png'}
|
||||
|
||||
@@ -30,10 +30,17 @@ from tests.test_builders.xpath_data import FIGURE_CAPTION
|
||||
from tests.test_builders.xpath_util import check_xpath
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from collections.abc import Callable, Sequence
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
from xml.etree.ElementTree import Element, ElementTree
|
||||
|
||||
from sphinx.testing.util import SphinxTestApp
|
||||
|
||||
|
||||
def test_html_sidebars_error(make_app, tmp_path):
|
||||
def test_html_sidebars_error(
|
||||
make_app: Callable[..., SphinxTestApp], tmp_path: Path
|
||||
) -> None:
|
||||
(tmp_path / 'conf.py').touch()
|
||||
with pytest.raises(
|
||||
ConfigError,
|
||||
@@ -48,7 +55,7 @@ def test_html_sidebars_error(make_app, tmp_path):
|
||||
)
|
||||
|
||||
|
||||
def test_html4_error(make_app, tmp_path):
|
||||
def test_html4_error(make_app: Callable[..., SphinxTestApp], tmp_path: Path) -> None:
|
||||
(tmp_path / 'conf.py').touch()
|
||||
with pytest.raises(
|
||||
ConfigError,
|
||||
@@ -137,7 +144,13 @@ def test_html4_error(make_app, tmp_path):
|
||||
)
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.test_params(shared_result='test_build_html_output_docutils18')
|
||||
def test_docutils_output(app, cached_etree_parse, fname, path, check):
|
||||
def test_docutils_output(
|
||||
app: SphinxTestApp,
|
||||
cached_etree_parse: Callable[[Path], ElementTree],
|
||||
fname: str,
|
||||
path: str,
|
||||
check: str,
|
||||
) -> None:
|
||||
app.build()
|
||||
check_xpath(cached_etree_parse(app.outdir / fname), fname, path, check)
|
||||
|
||||
@@ -186,7 +199,7 @@ def test_html_translator(app: SphinxTestApp) -> None:
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'expect',
|
||||
('path', 'check', 'be_found'),
|
||||
[
|
||||
(FIGURE_CAPTION + "//span[@class='caption-number']", 'Fig. 1', True),
|
||||
(FIGURE_CAPTION + "//span[@class='caption-number']", 'Fig. 2', True),
|
||||
@@ -205,9 +218,21 @@ def test_html_translator(app: SphinxTestApp) -> None:
|
||||
testroot='add_enumerable_node',
|
||||
srcdir='test_enumerable_node',
|
||||
)
|
||||
def test_enumerable_node(app, cached_etree_parse, expect):
|
||||
def test_enumerable_node(
|
||||
app: SphinxTestApp,
|
||||
cached_etree_parse: Callable[[Path], ElementTree],
|
||||
path: str,
|
||||
check: str,
|
||||
be_found: bool,
|
||||
) -> None:
|
||||
app.build()
|
||||
check_xpath(cached_etree_parse(app.outdir / 'index.html'), 'index.html', *expect)
|
||||
check_xpath(
|
||||
cached_etree_parse(app.outdir / 'index.html'),
|
||||
'index.html',
|
||||
path,
|
||||
check,
|
||||
be_found,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.sphinx(
|
||||
@@ -336,7 +361,7 @@ def test_html_raw_directive(app: SphinxTestApp) -> None:
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'expect',
|
||||
('path', 'check', 'be_found'),
|
||||
[
|
||||
(".//link[@href='_static/persistent.css'][@rel='stylesheet']", '', True),
|
||||
(
|
||||
@@ -383,9 +408,21 @@ def test_html_raw_directive(app: SphinxTestApp) -> None:
|
||||
],
|
||||
)
|
||||
@pytest.mark.sphinx('html', testroot='stylesheets')
|
||||
def test_alternate_stylesheets(app, cached_etree_parse, expect):
|
||||
def test_alternate_stylesheets(
|
||||
app: SphinxTestApp,
|
||||
cached_etree_parse: Callable[[Path], ElementTree],
|
||||
path: str,
|
||||
check: str,
|
||||
be_found: bool,
|
||||
) -> None:
|
||||
app.build()
|
||||
check_xpath(cached_etree_parse(app.outdir / 'index.html'), 'index.html', *expect)
|
||||
check_xpath(
|
||||
cached_etree_parse(app.outdir / 'index.html'),
|
||||
'index.html',
|
||||
path,
|
||||
check,
|
||||
be_found,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='html_style')
|
||||
@@ -478,12 +515,12 @@ def test_html_sidebar(app: SphinxTestApp) -> None:
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
('fname', 'expect'),
|
||||
('fname', 'path', 'check', 'be_found'),
|
||||
[
|
||||
('index.html', (".//h1/em/a[@href='https://example.com/cp.1']", '', True)),
|
||||
('index.html', (".//em/a[@href='https://example.com/man.1']", '', True)),
|
||||
('index.html', (".//em/a[@href='https://example.com/ls.1']", '', True)),
|
||||
('index.html', (".//em/a[@href='https://example.com/sphinx.']", '', True)),
|
||||
('index.html', ".//h1/em/a[@href='https://example.com/cp.1']", '', True),
|
||||
('index.html', ".//em/a[@href='https://example.com/man.1']", '', True),
|
||||
('index.html', ".//em/a[@href='https://example.com/ls.1']", '', True),
|
||||
('index.html', ".//em/a[@href='https://example.com/sphinx.']", '', True),
|
||||
],
|
||||
)
|
||||
@pytest.mark.sphinx(
|
||||
@@ -492,9 +529,16 @@ def test_html_sidebar(app: SphinxTestApp) -> None:
|
||||
confoverrides={'manpages_url': 'https://example.com/{page}.{section}'},
|
||||
)
|
||||
@pytest.mark.test_params(shared_result='test_build_html_manpage_url')
|
||||
def test_html_manpage(app, cached_etree_parse, fname, expect):
|
||||
def test_html_manpage(
|
||||
app: SphinxTestApp,
|
||||
cached_etree_parse: Callable[[Path], ElementTree],
|
||||
fname: str,
|
||||
path: str,
|
||||
check: str,
|
||||
be_found: bool,
|
||||
) -> None:
|
||||
app.build()
|
||||
check_xpath(cached_etree_parse(app.outdir / fname), fname, *expect)
|
||||
check_xpath(cached_etree_parse(app.outdir / fname), fname, path, check, be_found)
|
||||
|
||||
|
||||
@pytest.mark.sphinx(
|
||||
@@ -629,7 +673,7 @@ def test_html_remove_sources_before_write_gh_issue_10786(app: SphinxTestApp) ->
|
||||
# See: https://github.com/sphinx-doc/sphinx/issues/10786
|
||||
target = app.srcdir / 'img.png'
|
||||
|
||||
def handler(app):
|
||||
def handler(app: SphinxTestApp) -> list[tuple[str, dict[str, Any], str]]:
|
||||
assert target.exists()
|
||||
target.unlink()
|
||||
return []
|
||||
@@ -651,7 +695,9 @@ def test_html_remove_sources_before_write_gh_issue_10786(app: SphinxTestApp) ->
|
||||
testroot='domain-py-python_maximum_signature_line_length',
|
||||
confoverrides={'python_maximum_signature_line_length': 1},
|
||||
)
|
||||
def test_html_pep_695_one_type_per_line(app, cached_etree_parse):
|
||||
def test_html_pep_695_one_type_per_line(
|
||||
app: SphinxTestApp, cached_etree_parse: Callable[[Path], ElementTree]
|
||||
) -> None:
|
||||
app.build()
|
||||
fname = app.outdir / 'index.html'
|
||||
etree = cached_etree_parse(fname)
|
||||
@@ -660,7 +706,7 @@ def test_html_pep_695_one_type_per_line(app, cached_etree_parse):
|
||||
def __init__(self, expect: str) -> None:
|
||||
self.expect = expect
|
||||
|
||||
def __call__(self, nodes):
|
||||
def __call__(self, nodes: Sequence[Element]) -> None:
|
||||
assert len(nodes) == 1, nodes
|
||||
objnode = ''.join(nodes[0].itertext()).replace('\n\n', '')
|
||||
objnode = objnode.rstrip(chr(182)) # remove '¶' symbol
|
||||
@@ -719,7 +765,7 @@ def test_html_pep_695_trailing_comma_in_multi_line_signatures(
|
||||
def __init__(self, expect: str) -> None:
|
||||
self.expect = expect
|
||||
|
||||
def __call__(self, nodes):
|
||||
def __call__(self, nodes: Sequence[Element]) -> None:
|
||||
assert len(nodes) == 1, nodes
|
||||
objnode = ''.join(nodes[0].itertext()).replace('\n\n', '')
|
||||
objnode = objnode.rstrip(chr(182)) # remove '¶' symbol
|
||||
@@ -765,15 +811,17 @@ def test_html_admonition_collapse(app: SphinxTestApp) -> None:
|
||||
fname = app.outdir / 'index.html'
|
||||
etree = etree_parse(fname)
|
||||
|
||||
def _create_check(text: str, open: bool): # type: ignore[no-untyped-def]
|
||||
def _check(els):
|
||||
def _create_check(text: str, open: bool) -> Callable[[Sequence[Element]], None]:
|
||||
def _check(els: Sequence[Element]) -> None:
|
||||
assert len(els) == 1
|
||||
el = els[0]
|
||||
if open:
|
||||
assert el.attrib['open'] == 'open'
|
||||
else:
|
||||
assert 'open' not in el.attrib
|
||||
assert el.find('p').text == text
|
||||
p = el.find('p')
|
||||
assert p is not None
|
||||
assert p.text == text
|
||||
|
||||
return _check
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ ts_re = re.compile(r'.*\[(?P<ts>.*)\].*')
|
||||
if TYPE_CHECKING:
|
||||
from collections.abc import Callable, Iterable
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
from typing import Any, Self
|
||||
|
||||
from urllib3 import HTTPConnectionPool
|
||||
|
||||
@@ -53,7 +53,7 @@ if TYPE_CHECKING:
|
||||
class DefaultsHandler(BaseHTTPRequestHandler):
|
||||
protocol_version = 'HTTP/1.1'
|
||||
|
||||
def do_HEAD(self):
|
||||
def do_HEAD(self) -> None:
|
||||
if self.path[1:].rstrip() in {'', 'anchor.html'}:
|
||||
self.send_response(200, 'OK')
|
||||
self.send_header('Content-Length', '0')
|
||||
@@ -63,7 +63,7 @@ class DefaultsHandler(BaseHTTPRequestHandler):
|
||||
self.send_header('Content-Length', '0')
|
||||
self.end_headers()
|
||||
|
||||
def do_GET(self):
|
||||
def do_GET(self) -> None:
|
||||
if self.path[1:].rstrip() == '':
|
||||
content = b'ok\n\n'
|
||||
elif self.path[1:].rstrip() == 'anchor.html':
|
||||
@@ -95,25 +95,25 @@ class ConnectionMeasurement:
|
||||
new=self._collect_connections(),
|
||||
)
|
||||
|
||||
def _collect_connections(self) -> Callable[[object, str], HTTPConnectionPool]:
|
||||
def connection_collector(obj, url):
|
||||
def _collect_connections(self) -> Callable[[PoolManager, str], HTTPConnectionPool]:
|
||||
def connection_collector(obj: PoolManager, url: str) -> HTTPConnectionPool:
|
||||
connection = self.urllib3_connection_from_url(obj, url) # type: ignore[no-untyped-call]
|
||||
self.connections.add(connection)
|
||||
return connection
|
||||
|
||||
return connection_collector
|
||||
|
||||
def __enter__(self):
|
||||
def __enter__(self) -> Self:
|
||||
self.patcher.start()
|
||||
return self
|
||||
|
||||
def __exit__(self, *args, **kwargs):
|
||||
def __exit__(self, *args: object, **kwargs: Any) -> None:
|
||||
for connection in self.connections:
|
||||
connection.close()
|
||||
self.patcher.stop()
|
||||
|
||||
@property
|
||||
def connection_count(self):
|
||||
def connection_count(self) -> int:
|
||||
return len(self.connections)
|
||||
|
||||
|
||||
@@ -347,14 +347,14 @@ class AnchorsIgnoreForUrlHandler(BaseHTTPRequestHandler):
|
||||
return False
|
||||
return True
|
||||
|
||||
def do_HEAD(self):
|
||||
def do_HEAD(self) -> None:
|
||||
if self.path in {'/valid', '/ignored'}:
|
||||
self.send_response(200, 'OK')
|
||||
else:
|
||||
self.send_response(404, 'Not Found')
|
||||
self.end_headers()
|
||||
|
||||
def do_GET(self):
|
||||
def do_GET(self) -> None:
|
||||
if self.path == '/valid':
|
||||
self.send_response(200, 'OK')
|
||||
content = "<h1 id='valid-anchor'>valid anchor</h1>\n"
|
||||
@@ -424,7 +424,7 @@ def test_raises_for_invalid_status(app: SphinxTestApp) -> None:
|
||||
class InternalServerErrorHandler(BaseHTTPRequestHandler):
|
||||
protocol_version = 'HTTP/1.1'
|
||||
|
||||
def do_GET(self):
|
||||
def do_GET(self) -> None:
|
||||
self.send_error(500, 'Internal Server Error')
|
||||
|
||||
with serve_application(app, InternalServerErrorHandler) as address:
|
||||
@@ -446,7 +446,7 @@ def test_incomplete_html_anchor(app: SphinxTestApp) -> None:
|
||||
class IncompleteHTMLDocumentHandler(BaseHTTPRequestHandler):
|
||||
protocol_version = 'HTTP/1.1'
|
||||
|
||||
def do_GET(self):
|
||||
def do_GET(self) -> None:
|
||||
content = b'this is <div id="anchor">not</div> a valid HTML document'
|
||||
self.send_response(200, 'OK')
|
||||
self.send_header('Content-Length', str(len(content)))
|
||||
@@ -472,7 +472,7 @@ def test_decoding_error_anchor_ignored(app: SphinxTestApp) -> None:
|
||||
class NonASCIIHandler(BaseHTTPRequestHandler):
|
||||
protocol_version = 'HTTP/1.1'
|
||||
|
||||
def do_GET(self):
|
||||
def do_GET(self) -> None:
|
||||
content = b'\x80\x00\x80\x00' # non-ASCII byte-string
|
||||
self.send_response(200, 'OK')
|
||||
self.send_header('Content-Length', str(len(content)))
|
||||
@@ -491,7 +491,7 @@ def test_decoding_error_anchor_ignored(app: SphinxTestApp) -> None:
|
||||
|
||||
def custom_handler(
|
||||
valid_credentials: tuple[str, str] | None = None,
|
||||
success_criteria: Callable[[Any], bool] = lambda _: True,
|
||||
success_criteria: Callable[[BaseHTTPRequestHandler], bool] = lambda _: True,
|
||||
) -> type[BaseHTTPRequestHandler]:
|
||||
"""Returns an HTTP request handler that authenticates the client and then determines
|
||||
an appropriate HTTP response code, based on caller-provided credentials and optional
|
||||
@@ -526,11 +526,11 @@ def custom_handler(
|
||||
protocol_version = 'HTTP/1.1'
|
||||
|
||||
@authenticated
|
||||
def do_HEAD(self):
|
||||
def do_HEAD(self) -> None:
|
||||
self.do_GET()
|
||||
|
||||
@authenticated
|
||||
def do_GET(self):
|
||||
def do_GET(self) -> None:
|
||||
if success_criteria(self):
|
||||
self.send_response(200, 'OK')
|
||||
self.send_header('Content-Length', '0')
|
||||
@@ -608,7 +608,7 @@ def test_auth_header_no_match(app: SphinxTestApp) -> None:
|
||||
freshenv=True,
|
||||
)
|
||||
def test_linkcheck_request_headers(app: SphinxTestApp) -> None:
|
||||
def check_headers(self):
|
||||
def check_headers(self: BaseHTTPRequestHandler) -> bool:
|
||||
if 'X-Secret' in self.headers:
|
||||
return False
|
||||
return self.headers['Accept'] == 'text/html'
|
||||
@@ -634,7 +634,7 @@ def test_linkcheck_request_headers(app: SphinxTestApp) -> None:
|
||||
freshenv=True,
|
||||
)
|
||||
def test_linkcheck_request_headers_no_slash(app: SphinxTestApp) -> None:
|
||||
def check_headers(self):
|
||||
def check_headers(self: BaseHTTPRequestHandler) -> bool:
|
||||
if 'X-Secret' in self.headers:
|
||||
return False
|
||||
return self.headers['Accept'] == 'application/json'
|
||||
@@ -666,7 +666,7 @@ def test_linkcheck_request_headers_no_slash(app: SphinxTestApp) -> None:
|
||||
},
|
||||
)
|
||||
def test_linkcheck_request_headers_default(app: SphinxTestApp) -> None:
|
||||
def check_headers(self):
|
||||
def check_headers(self: BaseHTTPRequestHandler) -> bool:
|
||||
if self.headers['X-Secret'] != 'open sesami':
|
||||
return False
|
||||
return self.headers['Accept'] != 'application/json'
|
||||
@@ -701,7 +701,7 @@ def make_redirect_handler(*, support_head: bool = True) -> type[BaseHTTPRequestH
|
||||
self.send_header('Content-Length', '0')
|
||||
self.end_headers()
|
||||
|
||||
def log_date_time_string(self):
|
||||
def log_date_time_string(self) -> str:
|
||||
"""Strip date and time from logged messages for assertions."""
|
||||
return ''
|
||||
|
||||
@@ -713,7 +713,9 @@ def make_redirect_handler(*, support_head: bool = True) -> type[BaseHTTPRequestH
|
||||
testroot='linkcheck-localserver',
|
||||
freshenv=True,
|
||||
)
|
||||
def test_follows_redirects_on_HEAD(app, capsys):
|
||||
def test_follows_redirects_on_HEAD(
|
||||
app: SphinxTestApp, capsys: pytest.CaptureFixture[str]
|
||||
) -> None:
|
||||
with serve_application(app, make_redirect_handler(support_head=True)) as address:
|
||||
compile_linkcheck_allowed_redirects(app, app.config)
|
||||
app.build()
|
||||
@@ -740,7 +742,9 @@ def test_follows_redirects_on_HEAD(app, capsys):
|
||||
testroot='linkcheck-localserver',
|
||||
freshenv=True,
|
||||
)
|
||||
def test_follows_redirects_on_GET(app, capsys):
|
||||
def test_follows_redirects_on_GET(
|
||||
app: SphinxTestApp, capsys: pytest.CaptureFixture[str]
|
||||
) -> None:
|
||||
with serve_application(app, make_redirect_handler(support_head=False)) as address:
|
||||
compile_linkcheck_allowed_redirects(app, app.config)
|
||||
app.build()
|
||||
@@ -769,7 +773,9 @@ def test_follows_redirects_on_GET(app, capsys):
|
||||
freshenv=True,
|
||||
confoverrides={'linkcheck_allowed_redirects': {}}, # warn about any redirects
|
||||
)
|
||||
def test_warns_disallowed_redirects(app, capsys):
|
||||
def test_warns_disallowed_redirects(
|
||||
app: SphinxTestApp, capsys: pytest.CaptureFixture[str]
|
||||
) -> None:
|
||||
with serve_application(app, make_redirect_handler()) as address:
|
||||
compile_linkcheck_allowed_redirects(app, app.config)
|
||||
app.build()
|
||||
@@ -848,12 +854,12 @@ def test_linkcheck_allowed_redirects(app: SphinxTestApp) -> None:
|
||||
class OKHandler(BaseHTTPRequestHandler):
|
||||
protocol_version = 'HTTP/1.1'
|
||||
|
||||
def do_HEAD(self):
|
||||
def do_HEAD(self) -> None:
|
||||
self.send_response(200, 'OK')
|
||||
self.send_header('Content-Length', '0')
|
||||
self.end_headers()
|
||||
|
||||
def do_GET(self):
|
||||
def do_GET(self) -> None:
|
||||
content = b'ok\n'
|
||||
self.send_response(200, 'OK')
|
||||
self.send_header('Content-Length', str(len(content)))
|
||||
@@ -867,7 +873,7 @@ class OKHandler(BaseHTTPRequestHandler):
|
||||
testroot='linkcheck-localserver-https',
|
||||
freshenv=True,
|
||||
)
|
||||
def test_invalid_ssl(get_request, app):
|
||||
def test_invalid_ssl(get_request: mock.Mock, app: SphinxTestApp) -> None:
|
||||
# Link indicates SSL should be used (https) but the server does not handle it.
|
||||
with serve_application(app, OKHandler) as address:
|
||||
app.build()
|
||||
@@ -949,7 +955,9 @@ def test_connect_to_selfsigned_with_tls_cacerts(app: SphinxTestApp) -> None:
|
||||
testroot='linkcheck-localserver-https',
|
||||
freshenv=True,
|
||||
)
|
||||
def test_connect_to_selfsigned_with_requests_env_var(monkeypatch, app):
|
||||
def test_connect_to_selfsigned_with_requests_env_var(
|
||||
monkeypatch: pytest.MonkeyPatch, app: SphinxTestApp
|
||||
) -> None:
|
||||
monkeypatch.setenv('REQUESTS_CA_BUNDLE', CERT_FILE)
|
||||
with serve_application(app, OKHandler, tls_enabled=True) as address:
|
||||
app.build()
|
||||
@@ -991,13 +999,13 @@ def test_connect_to_selfsigned_nonexistent_cert_file(app: SphinxTestApp) -> None
|
||||
class InfiniteRedirectOnHeadHandler(BaseHTTPRequestHandler):
|
||||
protocol_version = 'HTTP/1.1'
|
||||
|
||||
def do_HEAD(self):
|
||||
def do_HEAD(self) -> None:
|
||||
self.send_response(302, 'Found')
|
||||
self.send_header('Location', '/redirected')
|
||||
self.send_header('Content-Length', '0')
|
||||
self.end_headers()
|
||||
|
||||
def do_GET(self):
|
||||
def do_GET(self) -> None:
|
||||
content = b'ok\n'
|
||||
self.send_response(200, 'OK')
|
||||
self.send_header('Content-Length', str(len(content)))
|
||||
@@ -1013,7 +1021,9 @@ class InfiniteRedirectOnHeadHandler(BaseHTTPRequestHandler):
|
||||
testroot='linkcheck-localserver',
|
||||
freshenv=True,
|
||||
)
|
||||
def test_TooManyRedirects_on_HEAD(app, monkeypatch):
|
||||
def test_TooManyRedirects_on_HEAD(
|
||||
app: SphinxTestApp, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
import requests.sessions
|
||||
|
||||
monkeypatch.setattr(requests.sessions, 'DEFAULT_REDIRECT_LIMIT', 5)
|
||||
@@ -1054,7 +1064,7 @@ def test_ignore_local_redirection(app: SphinxTestApp) -> None:
|
||||
class RemoteDomainRedirectHandler(InfiniteRedirectOnHeadHandler):
|
||||
protocol_version = 'HTTP/1.1'
|
||||
|
||||
def do_GET(self):
|
||||
def do_GET(self) -> None:
|
||||
self.send_response(301, 'Found')
|
||||
if self.path == '/':
|
||||
self.send_header('Location', '/local')
|
||||
@@ -1088,7 +1098,7 @@ def make_retry_after_handler(
|
||||
class RetryAfterHandler(BaseHTTPRequestHandler):
|
||||
protocol_version = 'HTTP/1.1'
|
||||
|
||||
def do_HEAD(self):
|
||||
def do_HEAD(self) -> None:
|
||||
status, retry_after = responses.pop(0)
|
||||
self.send_response(status)
|
||||
if retry_after:
|
||||
@@ -1096,7 +1106,7 @@ def make_retry_after_handler(
|
||||
self.send_header('Content-Length', '0')
|
||||
self.end_headers()
|
||||
|
||||
def log_date_time_string(self):
|
||||
def log_date_time_string(self) -> str:
|
||||
"""Strip date and time from logged messages for assertions."""
|
||||
return ''
|
||||
|
||||
@@ -1108,7 +1118,9 @@ def make_retry_after_handler(
|
||||
testroot='linkcheck-localserver',
|
||||
freshenv=True,
|
||||
)
|
||||
def test_too_many_requests_retry_after_int_delay(app, capsys):
|
||||
def test_too_many_requests_retry_after_int_delay(
|
||||
app: SphinxTestApp, capsys: pytest.CaptureFixture[str]
|
||||
) -> None:
|
||||
with (
|
||||
serve_application(
|
||||
app, make_retry_after_handler([(429, '0'), (200, None)])
|
||||
@@ -1143,7 +1155,12 @@ def test_too_many_requests_retry_after_int_delay(app, capsys):
|
||||
testroot='linkcheck-localserver',
|
||||
freshenv=True,
|
||||
)
|
||||
def test_too_many_requests_retry_after_HTTP_date(tz, app, monkeypatch, capsys):
|
||||
def test_too_many_requests_retry_after_HTTP_date(
|
||||
tz: str | None,
|
||||
app: SphinxTestApp,
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
capsys: pytest.CaptureFixture[str],
|
||||
) -> None:
|
||||
retry_after = wsgiref.handlers.format_date_time(time.time())
|
||||
|
||||
with monkeypatch.context() as m:
|
||||
@@ -1189,7 +1206,9 @@ def test_too_many_requests_retry_after_HTTP_date(tz, app, monkeypatch, capsys):
|
||||
testroot='linkcheck-localserver',
|
||||
freshenv=True,
|
||||
)
|
||||
def test_too_many_requests_retry_after_without_header(app, capsys):
|
||||
def test_too_many_requests_retry_after_without_header(
|
||||
app: SphinxTestApp, capsys: pytest.CaptureFixture[str]
|
||||
) -> None:
|
||||
with (
|
||||
serve_application(
|
||||
app, make_retry_after_handler([(429, None), (200, None)])
|
||||
@@ -1228,7 +1247,7 @@ def test_requests_timeout(app: SphinxTestApp) -> None:
|
||||
class DelayedResponseHandler(BaseHTTPRequestHandler):
|
||||
protocol_version = 'HTTP/1.1'
|
||||
|
||||
def do_GET(self):
|
||||
def do_GET(self) -> None:
|
||||
time.sleep(0.2) # wait before sending any response data
|
||||
self.send_response(200, 'OK')
|
||||
self.send_header('Content-Length', '0')
|
||||
@@ -1329,7 +1348,9 @@ def test_limit_rate_bails_out_after_waiting_max_time(app: SphinxTestApp) -> None
|
||||
|
||||
@mock.patch('sphinx.util.requests.requests.Session.get_adapter')
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
def test_connection_contention(get_adapter, app, capsys):
|
||||
def test_connection_contention(
|
||||
get_adapter: mock.Mock, app: SphinxTestApp, capsys: pytest.CaptureFixture[str]
|
||||
) -> None:
|
||||
# Create a shared, but limited-size, connection pool
|
||||
import requests
|
||||
|
||||
@@ -1380,10 +1401,10 @@ def test_connection_contention(get_adapter, app, capsys):
|
||||
class ConnectionResetHandler(BaseHTTPRequestHandler):
|
||||
protocol_version = 'HTTP/1.1'
|
||||
|
||||
def do_HEAD(self):
|
||||
def do_HEAD(self) -> None:
|
||||
self.close_connection = True
|
||||
|
||||
def do_GET(self):
|
||||
def do_GET(self) -> None:
|
||||
self.send_response(200, 'OK')
|
||||
self.send_header('Content-Length', '0')
|
||||
self.end_headers()
|
||||
@@ -1446,7 +1467,7 @@ class CapitalisePathHandler(BaseHTTPRequestHandler):
|
||||
|
||||
protocol_version = 'HTTP/1.1'
|
||||
|
||||
def do_GET(self):
|
||||
def do_GET(self) -> None:
|
||||
if self.path.islower():
|
||||
# Redirect lowercase paths to uppercase versions
|
||||
self.send_response(301, 'Moved Permanently')
|
||||
|
||||
@@ -250,7 +250,7 @@ def test_LiteralIncludeReader_dedent_and_append_and_prepend(
|
||||
assert content == 'class Foo:\n def baz():\n pass\n\n# comment\n'
|
||||
|
||||
|
||||
def test_LiteralIncludeReader_tabwidth(testroot):
|
||||
def test_LiteralIncludeReader_tabwidth(testroot: Path) -> None:
|
||||
# tab-width: 4
|
||||
options = {'tab-width': 4, 'pyobject': 'Qux'}
|
||||
reader = LiteralIncludeReader(testroot / 'target.py', options, DUMMY_CONFIG)
|
||||
@@ -264,14 +264,14 @@ def test_LiteralIncludeReader_tabwidth(testroot):
|
||||
assert content == 'class Qux:\n def quux(self):\n pass\n'
|
||||
|
||||
|
||||
def test_LiteralIncludeReader_tabwidth_dedent(testroot):
|
||||
def test_LiteralIncludeReader_tabwidth_dedent(testroot: Path) -> None:
|
||||
options = {'tab-width': 4, 'dedent': 4, 'pyobject': 'Qux.quux'}
|
||||
reader = LiteralIncludeReader(testroot / 'target.py', options, DUMMY_CONFIG)
|
||||
content, _lines = reader.read()
|
||||
assert content == 'def quux(self):\n pass\n'
|
||||
|
||||
|
||||
def test_LiteralIncludeReader_diff(testroot, literal_inc_path):
|
||||
def test_LiteralIncludeReader_diff(testroot: Path, literal_inc_path: Path) -> None:
|
||||
literal_diff_path = testroot / 'literal-diff.inc'
|
||||
options = {'diff': literal_diff_path}
|
||||
reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG)
|
||||
|
||||
@@ -9,6 +9,14 @@ from sphinx import addnodes
|
||||
from sphinx.testing import restructuredtext
|
||||
from sphinx.testing.util import assert_node
|
||||
|
||||
TYPE_CHECKING = False
|
||||
if TYPE_CHECKING:
|
||||
from typing import TypeAlias
|
||||
|
||||
from sphinx.testing.util import SphinxTestApp
|
||||
|
||||
_IndexEntry: TypeAlias = tuple[str, str, str, str, str | None]
|
||||
|
||||
DOMAINS = [
|
||||
# directive, no-index, no-index-entry, signature of f, signature of g, index entry of g
|
||||
(
|
||||
@@ -76,8 +84,14 @@ DOMAINS = [
|
||||
)
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
def test_object_description_no_typesetting(
|
||||
app, directive, no_index, no_index_entry, sig_f, sig_g, index_g
|
||||
):
|
||||
app: SphinxTestApp,
|
||||
directive: str,
|
||||
no_index: bool,
|
||||
no_index_entry: bool,
|
||||
sig_f: str,
|
||||
sig_g: str,
|
||||
index_g: _IndexEntry,
|
||||
) -> None:
|
||||
text = f'.. {directive}:: {sig_f}\n :no-typesetting:\n'
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
assert_node(doctree, (addnodes.index, nodes.target))
|
||||
@@ -89,8 +103,14 @@ def test_object_description_no_typesetting(
|
||||
)
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
def test_object_description_no_typesetting_twice(
|
||||
app, directive, no_index, no_index_entry, sig_f, sig_g, index_g
|
||||
):
|
||||
app: SphinxTestApp,
|
||||
directive: str,
|
||||
no_index: bool,
|
||||
no_index_entry: bool,
|
||||
sig_f: str,
|
||||
sig_g: str,
|
||||
index_g: _IndexEntry,
|
||||
) -> None:
|
||||
text = (
|
||||
f'.. {directive}:: {sig_f}\n'
|
||||
f' :no-typesetting:\n'
|
||||
@@ -108,8 +128,14 @@ def test_object_description_no_typesetting_twice(
|
||||
)
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
def test_object_description_no_typesetting_noindex_orig(
|
||||
app, directive, no_index, no_index_entry, sig_f, sig_g, index_g
|
||||
):
|
||||
app: SphinxTestApp,
|
||||
directive: str,
|
||||
no_index: bool,
|
||||
no_index_entry: bool,
|
||||
sig_f: str,
|
||||
sig_g: str,
|
||||
index_g: _IndexEntry,
|
||||
) -> None:
|
||||
if not no_index:
|
||||
pytest.skip(f'{directive} does not support :no-index: option')
|
||||
text = f'.. {directive}:: {sig_f}\n :no-index:\n.. {directive}:: {sig_g}\n'
|
||||
@@ -124,8 +150,14 @@ def test_object_description_no_typesetting_noindex_orig(
|
||||
)
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
def test_object_description_no_typesetting_noindex(
|
||||
app, directive, no_index, no_index_entry, sig_f, sig_g, index_g
|
||||
):
|
||||
app: SphinxTestApp,
|
||||
directive: str,
|
||||
no_index: bool,
|
||||
no_index_entry: bool,
|
||||
sig_f: str,
|
||||
sig_g: str,
|
||||
index_g: _IndexEntry,
|
||||
) -> None:
|
||||
if not no_index:
|
||||
pytest.skip(f'{directive} does not support :no-index: option')
|
||||
text = (
|
||||
@@ -147,8 +179,14 @@ def test_object_description_no_typesetting_noindex(
|
||||
)
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
def test_object_description_no_typesetting_no_index_entry(
|
||||
app, directive, no_index, no_index_entry, sig_f, sig_g, index_g
|
||||
):
|
||||
app: SphinxTestApp,
|
||||
directive: str,
|
||||
no_index: bool,
|
||||
no_index_entry: bool,
|
||||
sig_f: str,
|
||||
sig_g: str,
|
||||
index_g: _IndexEntry,
|
||||
) -> None:
|
||||
if not no_index_entry:
|
||||
pytest.skip(f'{directive} does not support :no-index-entry: option')
|
||||
text = (
|
||||
@@ -170,8 +208,14 @@ def test_object_description_no_typesetting_no_index_entry(
|
||||
)
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
def test_object_description_no_typesetting_code(
|
||||
app, directive, no_index, no_index_entry, sig_f, sig_g, index_g
|
||||
):
|
||||
app: SphinxTestApp,
|
||||
directive: str,
|
||||
no_index: bool,
|
||||
no_index_entry: bool,
|
||||
sig_f: str,
|
||||
sig_g: str,
|
||||
index_g: _IndexEntry,
|
||||
) -> None:
|
||||
text = (
|
||||
f'.. {directive}:: {sig_f}\n'
|
||||
f' :no-typesetting:\n'
|
||||
@@ -201,8 +245,14 @@ def test_object_description_no_typesetting_code(
|
||||
)
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
def test_object_description_no_typesetting_heading(
|
||||
app, directive, no_index, no_index_entry, sig_f, sig_g, index_g
|
||||
):
|
||||
app: SphinxTestApp,
|
||||
directive: str,
|
||||
no_index: bool,
|
||||
no_index_entry: bool,
|
||||
sig_f: str,
|
||||
sig_g: str,
|
||||
index_g: _IndexEntry,
|
||||
) -> None:
|
||||
text = (
|
||||
f'.. {directive}:: {sig_f}\n'
|
||||
f' :no-typesetting:\n'
|
||||
|
||||
@@ -12,6 +12,12 @@ import pytest
|
||||
|
||||
from tests.test_ext_autodoc.autodoc_util import FakeEvents, do_autodoc
|
||||
|
||||
TYPE_CHECKING = False
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any
|
||||
|
||||
from sphinx.application import Sphinx
|
||||
|
||||
pytestmark = pytest.mark.usefixtures('inject_autodoc_root_into_sys_path')
|
||||
|
||||
|
||||
@@ -298,19 +304,22 @@ def test_show_inheritance_for_decendants_of_generic_type() -> None:
|
||||
]
|
||||
|
||||
|
||||
def _autodoc_process_bases(
|
||||
app: Sphinx, name: str, obj: Any, options: dict[str, bool], bases: list[type]
|
||||
) -> None:
|
||||
assert name == 'target.classes.Quux'
|
||||
assert obj.__module__ == 'target.classes'
|
||||
assert obj.__name__ == 'Quux'
|
||||
assert vars(options) == {}
|
||||
assert bases == [typing.List[typing.Union[int, float]]] # NoQA: UP006, UP007
|
||||
|
||||
bases.pop()
|
||||
bases.extend([int, str])
|
||||
|
||||
|
||||
def test_autodoc_process_bases() -> None:
|
||||
def autodoc_process_bases(app, name, obj, options, bases):
|
||||
assert name == 'target.classes.Quux'
|
||||
assert obj.__module__ == 'target.classes'
|
||||
assert obj.__name__ == 'Quux'
|
||||
assert vars(options) == {}
|
||||
assert bases == [typing.List[typing.Union[int, float]]] # NoQA: UP006, UP007
|
||||
|
||||
bases.pop()
|
||||
bases.extend([int, str])
|
||||
|
||||
events = FakeEvents()
|
||||
events.connect('autodoc-process-bases', autodoc_process_bases)
|
||||
events.connect('autodoc-process-bases', _autodoc_process_bases)
|
||||
|
||||
options = {'show-inheritance': None}
|
||||
actual = do_autodoc('class', 'target.classes.Quux', events=events, options=options)
|
||||
@@ -377,7 +386,7 @@ def test_class_doc_from_both() -> None:
|
||||
|
||||
|
||||
def test_class_alias() -> None:
|
||||
def autodoc_process_docstring(*args):
|
||||
def autodoc_process_docstring(*args: Any) -> None:
|
||||
"""A handler always raises an error.
|
||||
This confirms this handler is never called for class aliases.
|
||||
"""
|
||||
|
||||
@@ -17,7 +17,7 @@ if TYPE_CHECKING:
|
||||
|
||||
@pytest.mark.sphinx('dummy', testroot='ext-autosummary-import_cycle')
|
||||
@pytest.mark.usefixtures('rollback_sysmodules')
|
||||
def test_autosummary_import_cycle(app):
|
||||
def test_autosummary_import_cycle(app: SphinxTestApp) -> None:
|
||||
app.build()
|
||||
|
||||
doctree = app.env.get_doctree('index')
|
||||
@@ -46,12 +46,27 @@ def test_autosummary_import_cycle(app):
|
||||
addnodes.desc, # [6]
|
||||
),
|
||||
)
|
||||
doctree_4 = doctree[4]
|
||||
assert isinstance(doctree_4, nodes.Element)
|
||||
doctree_4_0 = doctree_4[0]
|
||||
assert isinstance(doctree_4_0, nodes.Element)
|
||||
doctree_4_0_0 = doctree_4_0[0]
|
||||
assert isinstance(doctree_4_0_0, nodes.Element)
|
||||
doctree_4_0_0_2 = doctree_4_0_0[2]
|
||||
assert isinstance(doctree_4_0_0_2, nodes.Element)
|
||||
doctree_4_0_0_2_0 = doctree_4_0_0_2[0]
|
||||
assert isinstance(doctree_4_0_0_2_0, nodes.Element)
|
||||
doctree_4_0_0_2_0_0 = doctree_4_0_0_2_0[0]
|
||||
assert isinstance(doctree_4_0_0_2_0_0, nodes.Element)
|
||||
doctree_4_0_0_2_0_0_0 = doctree_4_0_0_2_0_0[0]
|
||||
assert isinstance(doctree_4_0_0_2_0_0_0, nodes.Element)
|
||||
|
||||
assert_node(
|
||||
doctree[4][0][0][2][0],
|
||||
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],
|
||||
doctree_4_0_0_2_0_0_0[0],
|
||||
nodes.reference,
|
||||
refid='spam.eggs.Ham',
|
||||
reftitle='spam.eggs.Ham',
|
||||
|
||||
@@ -18,9 +18,9 @@ from tests.utils import http_server
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from collections.abc import Iterable
|
||||
from pathlib import Path
|
||||
from typing import Any, BinaryIO
|
||||
|
||||
|
||||
BASE_CONFIG = {
|
||||
'extensions': ['sphinx.ext.intersphinx'],
|
||||
'intersphinx_timeout': 0.1,
|
||||
@@ -198,7 +198,7 @@ def make_inventory_handler(
|
||||
assert all(p.port == port for p in projects)
|
||||
|
||||
class InventoryHandler(BaseHTTPRequestHandler):
|
||||
def do_GET(self):
|
||||
def do_GET(self) -> None:
|
||||
self.send_response(200, 'OK')
|
||||
|
||||
data = b''
|
||||
@@ -225,7 +225,7 @@ def test_intersphinx_project_fixture() -> None:
|
||||
assert project.url == 'http://localhost:9341/route'
|
||||
|
||||
|
||||
def test_load_mappings_cache(tmp_path):
|
||||
def test_load_mappings_cache(tmp_path: Path) -> None:
|
||||
tmp_path.joinpath('conf.py').touch()
|
||||
tmp_path.joinpath('index.rst').touch()
|
||||
project = SingleEntryProject(1, 'a')
|
||||
@@ -249,7 +249,7 @@ def test_load_mappings_cache(tmp_path):
|
||||
assert inventories.named_inventory == {'spam': {'py:module': item}}
|
||||
|
||||
|
||||
def test_load_mappings_cache_update(tmp_path):
|
||||
def test_load_mappings_cache_update(tmp_path: Path) -> None:
|
||||
tmp_path.joinpath('conf.py').touch()
|
||||
tmp_path.joinpath('index.rst').touch()
|
||||
old_project = SingleEntryProject(1337, 'old')
|
||||
@@ -282,7 +282,7 @@ def test_load_mappings_cache_update(tmp_path):
|
||||
assert inventories.named_inventory == {'spam': {'py:module': item}}
|
||||
|
||||
|
||||
def test_load_mappings_cache_revert_update(tmp_path):
|
||||
def test_load_mappings_cache_revert_update(tmp_path: Path) -> None:
|
||||
tmp_path.joinpath('conf.py').touch()
|
||||
tmp_path.joinpath('index.rst').touch()
|
||||
old_project = SingleEntryProject(1337, 'old')
|
||||
|
||||
@@ -11,69 +11,77 @@ import pytest
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.ext.napoleon import Config, _process_docstring, _skip_member, setup
|
||||
|
||||
TYPE_CHECKING = False
|
||||
if TYPE_CHECKING:
|
||||
from collections.abc import Callable
|
||||
from typing import ParamSpec, TypeVar
|
||||
|
||||
def simple_decorator(f):
|
||||
_P = ParamSpec('_P')
|
||||
_R = TypeVar('_R')
|
||||
|
||||
|
||||
def simple_decorator(f: Callable[_P, _R]) -> Callable[_P, _R]:
|
||||
"""A simple decorator that does nothing, for tests to use."""
|
||||
|
||||
@functools.wraps(f)
|
||||
def wrapper(*args, **kwargs):
|
||||
def wrapper(*args: _P.args, **kwargs: _P.kwargs) -> _R:
|
||||
return f(*args, **kwargs)
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
def _private_doc():
|
||||
def _private_doc() -> None:
|
||||
"""module._private_doc.DOCSTRING"""
|
||||
pass
|
||||
|
||||
|
||||
def _private_undoc():
|
||||
def _private_undoc() -> None:
|
||||
pass
|
||||
|
||||
|
||||
def __special_doc__(): # NoQA: N807
|
||||
def __special_doc__() -> None: # NoQA: N807
|
||||
"""module.__special_doc__.DOCSTRING"""
|
||||
pass
|
||||
|
||||
|
||||
def __special_undoc__(): # NoQA: N807
|
||||
def __special_undoc__() -> None: # NoQA: N807
|
||||
pass
|
||||
|
||||
|
||||
class SampleClass:
|
||||
def _private_doc(self):
|
||||
def _private_doc(self) -> None:
|
||||
"""SampleClass._private_doc.DOCSTRING"""
|
||||
pass
|
||||
|
||||
def _private_undoc(self):
|
||||
def _private_undoc(self) -> None:
|
||||
pass
|
||||
|
||||
def __special_doc__(self): # NoQA: PLW3201
|
||||
def __special_doc__(self) -> None: # NoQA: PLW3201
|
||||
"""SampleClass.__special_doc__.DOCSTRING"""
|
||||
pass
|
||||
|
||||
def __special_undoc__(self): # NoQA: PLW3201
|
||||
def __special_undoc__(self) -> None: # NoQA: PLW3201
|
||||
pass
|
||||
|
||||
@simple_decorator
|
||||
def __decorated_func__(self): # NoQA: PLW3201
|
||||
def __decorated_func__(self) -> None: # NoQA: PLW3201
|
||||
"""Doc"""
|
||||
pass
|
||||
|
||||
|
||||
class SampleError(Exception):
|
||||
def _private_doc(self):
|
||||
def _private_doc(self) -> None:
|
||||
"""SampleError._private_doc.DOCSTRING"""
|
||||
pass
|
||||
|
||||
def _private_undoc(self):
|
||||
def _private_undoc(self) -> None:
|
||||
pass
|
||||
|
||||
def __special_doc__(self): # NoQA: PLW3201
|
||||
def __special_doc__(self) -> None: # NoQA: PLW3201
|
||||
"""SampleError.__special_doc__.DOCSTRING"""
|
||||
pass
|
||||
|
||||
def __special_undoc__(self): # NoQA: PLW3201
|
||||
def __special_undoc__(self) -> None: # NoQA: PLW3201
|
||||
pass
|
||||
|
||||
|
||||
@@ -81,7 +89,7 @@ SampleNamedTuple = namedtuple('SampleNamedTuple', 'user_id block_type def_id')
|
||||
|
||||
|
||||
class TestProcessDocstring:
|
||||
def test_modify_in_place(self):
|
||||
def test_modify_in_place(self) -> None:
|
||||
lines = [
|
||||
'Summary line.',
|
||||
'',
|
||||
@@ -109,10 +117,10 @@ class TestProcessDocstring:
|
||||
|
||||
|
||||
class TestSetup:
|
||||
def test_unknown_app_type(self):
|
||||
def test_unknown_app_type(self) -> None:
|
||||
setup(object()) # type: ignore[arg-type]
|
||||
|
||||
def test_add_config_values(self):
|
||||
def test_add_config_values(self) -> None:
|
||||
app = mock.Mock(Sphinx)
|
||||
setup(app)
|
||||
for name, _default, _rebuild, _types in Config._config_values:
|
||||
@@ -160,7 +168,7 @@ class TestSkipMember:
|
||||
setattr(app.config, config_name, False)
|
||||
assert None is _skip_member(app, what, member, obj, skip, mock.Mock())
|
||||
|
||||
def test_namedtuple(self):
|
||||
def test_namedtuple(self) -> None:
|
||||
# Since python 3.7, namedtuple._asdict() has not been documented
|
||||
# because there is no way to check the method is a member of the
|
||||
# namedtuple class. This testcase confirms only it does not
|
||||
@@ -174,7 +182,7 @@ class TestSkipMember:
|
||||
'napoleon_include_private_with_doc',
|
||||
)
|
||||
|
||||
def test_class_private_doc(self):
|
||||
def test_class_private_doc(self) -> None:
|
||||
self.assert_skip(
|
||||
'class',
|
||||
'_private_doc',
|
||||
@@ -183,7 +191,7 @@ class TestSkipMember:
|
||||
'napoleon_include_private_with_doc',
|
||||
)
|
||||
|
||||
def test_class_private_undoc(self):
|
||||
def test_class_private_undoc(self) -> None:
|
||||
self.assert_skip(
|
||||
'class',
|
||||
'_private_undoc',
|
||||
@@ -192,7 +200,7 @@ class TestSkipMember:
|
||||
'napoleon_include_private_with_doc',
|
||||
)
|
||||
|
||||
def test_class_special_doc(self):
|
||||
def test_class_special_doc(self) -> None:
|
||||
self.assert_skip(
|
||||
'class',
|
||||
'__special_doc__',
|
||||
@@ -201,7 +209,7 @@ class TestSkipMember:
|
||||
'napoleon_include_special_with_doc',
|
||||
)
|
||||
|
||||
def test_class_special_undoc(self):
|
||||
def test_class_special_undoc(self) -> None:
|
||||
self.assert_skip(
|
||||
'class',
|
||||
'__special_undoc__',
|
||||
@@ -210,7 +218,7 @@ class TestSkipMember:
|
||||
'napoleon_include_special_with_doc',
|
||||
)
|
||||
|
||||
def test_class_decorated_doc(self):
|
||||
def test_class_decorated_doc(self) -> None:
|
||||
self.assert_skip(
|
||||
'class',
|
||||
'__decorated_func__',
|
||||
@@ -219,7 +227,7 @@ class TestSkipMember:
|
||||
'napoleon_include_special_with_doc',
|
||||
)
|
||||
|
||||
def test_exception_private_doc(self):
|
||||
def test_exception_private_doc(self) -> None:
|
||||
self.assert_skip(
|
||||
'exception',
|
||||
'_private_doc',
|
||||
@@ -228,7 +236,7 @@ class TestSkipMember:
|
||||
'napoleon_include_private_with_doc',
|
||||
)
|
||||
|
||||
def test_exception_private_undoc(self):
|
||||
def test_exception_private_undoc(self) -> None:
|
||||
self.assert_skip(
|
||||
'exception',
|
||||
'_private_undoc',
|
||||
@@ -237,7 +245,7 @@ class TestSkipMember:
|
||||
'napoleon_include_private_with_doc',
|
||||
)
|
||||
|
||||
def test_exception_special_doc(self):
|
||||
def test_exception_special_doc(self) -> None:
|
||||
self.assert_skip(
|
||||
'exception',
|
||||
'__special_doc__',
|
||||
@@ -246,7 +254,7 @@ class TestSkipMember:
|
||||
'napoleon_include_special_with_doc',
|
||||
)
|
||||
|
||||
def test_exception_special_undoc(self):
|
||||
def test_exception_special_undoc(self) -> None:
|
||||
self.assert_skip(
|
||||
'exception',
|
||||
'__special_undoc__',
|
||||
@@ -255,7 +263,7 @@ class TestSkipMember:
|
||||
'napoleon_include_special_with_doc',
|
||||
)
|
||||
|
||||
def test_module_private_doc(self):
|
||||
def test_module_private_doc(self) -> None:
|
||||
self.assert_skip(
|
||||
'module',
|
||||
'_private_doc',
|
||||
@@ -264,7 +272,7 @@ class TestSkipMember:
|
||||
'napoleon_include_private_with_doc',
|
||||
)
|
||||
|
||||
def test_module_private_undoc(self):
|
||||
def test_module_private_undoc(self) -> None:
|
||||
self.assert_skip(
|
||||
'module',
|
||||
'_private_undoc',
|
||||
@@ -273,7 +281,7 @@ class TestSkipMember:
|
||||
'napoleon_include_private_with_doc',
|
||||
)
|
||||
|
||||
def test_module_special_doc(self):
|
||||
def test_module_special_doc(self) -> None:
|
||||
self.assert_skip(
|
||||
'module',
|
||||
'__special_doc__',
|
||||
@@ -282,7 +290,7 @@ class TestSkipMember:
|
||||
'napoleon_include_special_with_doc',
|
||||
)
|
||||
|
||||
def test_module_special_undoc(self):
|
||||
def test_module_special_undoc(self) -> None:
|
||||
self.assert_skip(
|
||||
'module',
|
||||
'__special_undoc__',
|
||||
|
||||
@@ -320,10 +320,14 @@ def test_imgmath_numfig_html(app: SphinxTestApp) -> None:
|
||||
|
||||
|
||||
@pytest.mark.sphinx('dummy', testroot='ext-math-compat')
|
||||
def test_math_compat(app):
|
||||
def test_math_compat(app: SphinxTestApp) -> None:
|
||||
with warnings.catch_warnings(record=True):
|
||||
app.build(force_all=True)
|
||||
doctree = app.env.get_and_resolve_doctree('index', app.builder, tags=app.tags)
|
||||
doctree_0 = doctree[0]
|
||||
assert isinstance(doctree_0, nodes.Element)
|
||||
doctree_0_1 = doctree_0[1]
|
||||
assert isinstance(doctree_0_1, nodes.Element)
|
||||
|
||||
assert_node(
|
||||
doctree,
|
||||
@@ -338,7 +342,7 @@ def test_math_compat(app):
|
||||
],
|
||||
)
|
||||
assert_node(
|
||||
doctree[0][1][1],
|
||||
doctree_0_1[1],
|
||||
(
|
||||
'Inline: ',
|
||||
[nodes.math, 'E=mc^2'],
|
||||
@@ -347,7 +351,7 @@ def test_math_compat(app):
|
||||
),
|
||||
)
|
||||
assert_node(
|
||||
doctree[0][2],
|
||||
doctree_0[2],
|
||||
(
|
||||
[nodes.title, 'block'],
|
||||
[nodes.math_block, 'a^2+b^2=c^2\n\n'],
|
||||
|
||||
@@ -2,11 +2,21 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import pytest
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from collections.abc import Callable
|
||||
|
||||
from sphinx.testing.fixtures import _app_params
|
||||
from sphinx.testing.util import SphinxTestApp
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='templating', copy_test_root=True)
|
||||
def test_layout_overloading(make_app, app_params):
|
||||
def test_layout_overloading(
|
||||
make_app: Callable[..., SphinxTestApp], app_params: _app_params
|
||||
) -> None:
|
||||
args, kwargs = app_params
|
||||
app = make_app(*args, **kwargs)
|
||||
app.build()
|
||||
@@ -16,7 +26,9 @@ def test_layout_overloading(make_app, app_params):
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='templating', copy_test_root=True)
|
||||
def test_autosummary_class_template_overloading(make_app, app_params):
|
||||
def test_autosummary_class_template_overloading(
|
||||
make_app: Callable[..., SphinxTestApp], app_params: _app_params
|
||||
) -> None:
|
||||
args, kwargs = app_params
|
||||
app = make_app(*args, **kwargs)
|
||||
app.build()
|
||||
@@ -34,7 +46,9 @@ def test_autosummary_class_template_overloading(make_app, app_params):
|
||||
confoverrides={'autosummary_context': {'sentence': 'foobar'}},
|
||||
copy_test_root=True,
|
||||
)
|
||||
def test_autosummary_context(make_app, app_params):
|
||||
def test_autosummary_context(
|
||||
make_app: Callable[..., SphinxTestApp], app_params: _app_params
|
||||
) -> None:
|
||||
args, kwargs = app_params
|
||||
app = make_app(*args, **kwargs)
|
||||
app.build()
|
||||
|
||||
+19
-10
@@ -10,11 +10,20 @@ import pytest
|
||||
from sphinx.testing.util import SphinxTestApp
|
||||
from sphinx.versioning import add_uids, get_ratio, merge_doctrees
|
||||
|
||||
TYPE_CHECKING = False
|
||||
if TYPE_CHECKING:
|
||||
from collections.abc import Iterator
|
||||
from pathlib import Path
|
||||
|
||||
from docutils import nodes
|
||||
|
||||
from sphinx.application import Sphinx
|
||||
|
||||
original = original_uids = None
|
||||
|
||||
|
||||
@pytest.fixture(scope='module', autouse=True)
|
||||
def _setup_module(rootdir, sphinx_test_tempdir):
|
||||
def _setup_module(rootdir: Path, sphinx_test_tempdir: Path) -> Iterator[None]:
|
||||
global original, original_uids # NoQA: PLW0603
|
||||
srcdir = sphinx_test_tempdir / 'test-versioning'
|
||||
if not srcdir.exists():
|
||||
@@ -32,11 +41,11 @@ def _setup_module(rootdir, sphinx_test_tempdir):
|
||||
doctrees = {}
|
||||
|
||||
|
||||
def on_doctree_resolved(app, doctree, docname):
|
||||
def on_doctree_resolved(app: Sphinx, doctree: nodes.document, docname: str) -> None:
|
||||
doctrees[docname] = doctree
|
||||
|
||||
|
||||
def is_paragraph(node):
|
||||
def is_paragraph(node: nodes.Node) -> bool:
|
||||
return node.__class__.__name__ == 'paragraph'
|
||||
|
||||
|
||||
@@ -64,7 +73,7 @@ def test_pickleablility() -> None:
|
||||
def test_modified() -> None:
|
||||
modified = doctrees['modified']
|
||||
new_nodes = list(merge_doctrees(original, modified, is_paragraph))
|
||||
uids = [n.uid for n in modified.findall(is_paragraph)]
|
||||
uids = [n.uid for n in modified.findall(is_paragraph)] # type: ignore[attr-defined]
|
||||
assert not new_nodes
|
||||
assert original_uids == uids
|
||||
|
||||
@@ -72,7 +81,7 @@ def test_modified() -> None:
|
||||
def test_added() -> None:
|
||||
added = doctrees['added']
|
||||
new_nodes = list(merge_doctrees(original, added, is_paragraph))
|
||||
uids = [n.uid for n in added.findall(is_paragraph)]
|
||||
uids = [n.uid for n in added.findall(is_paragraph)] # type: ignore[attr-defined]
|
||||
assert len(new_nodes) == 1
|
||||
assert original_uids == uids[:-1]
|
||||
|
||||
@@ -80,7 +89,7 @@ def test_added() -> None:
|
||||
def test_deleted() -> None:
|
||||
deleted = doctrees['deleted']
|
||||
new_nodes = list(merge_doctrees(original, deleted, is_paragraph))
|
||||
uids = [n.uid for n in deleted.findall(is_paragraph)]
|
||||
uids = [n.uid for n in deleted.findall(is_paragraph)] # type: ignore[attr-defined]
|
||||
assert not new_nodes
|
||||
assert original_uids[::2] == uids
|
||||
|
||||
@@ -88,7 +97,7 @@ def test_deleted() -> None:
|
||||
def test_deleted_end() -> None:
|
||||
deleted_end = doctrees['deleted_end']
|
||||
new_nodes = list(merge_doctrees(original, deleted_end, is_paragraph))
|
||||
uids = [n.uid for n in deleted_end.findall(is_paragraph)]
|
||||
uids = [n.uid for n in deleted_end.findall(is_paragraph)] # type: ignore[attr-defined]
|
||||
assert not new_nodes
|
||||
assert original_uids[:-1] == uids
|
||||
|
||||
@@ -96,7 +105,7 @@ def test_deleted_end() -> None:
|
||||
def test_insert() -> None:
|
||||
insert = doctrees['insert']
|
||||
new_nodes = list(merge_doctrees(original, insert, is_paragraph))
|
||||
uids = [n.uid for n in insert.findall(is_paragraph)]
|
||||
uids = [n.uid for n in insert.findall(is_paragraph)] # type: ignore[attr-defined]
|
||||
assert len(new_nodes) == 1
|
||||
assert original_uids[0] == uids[0]
|
||||
assert original_uids[1:] == uids[2:]
|
||||
@@ -105,7 +114,7 @@ def test_insert() -> None:
|
||||
def test_insert_beginning() -> None:
|
||||
insert_beginning = doctrees['insert_beginning']
|
||||
new_nodes = list(merge_doctrees(original, insert_beginning, is_paragraph))
|
||||
uids = [n.uid for n in insert_beginning.findall(is_paragraph)]
|
||||
uids = [n.uid for n in insert_beginning.findall(is_paragraph)] # type: ignore[attr-defined]
|
||||
assert len(new_nodes) == 1
|
||||
assert len(uids) == 4
|
||||
assert original_uids == uids[1:]
|
||||
@@ -115,7 +124,7 @@ def test_insert_beginning() -> None:
|
||||
def test_insert_similar() -> None:
|
||||
insert_similar = doctrees['insert_similar']
|
||||
new_nodes = list(merge_doctrees(original, insert_similar, is_paragraph))
|
||||
uids = [n.uid for n in insert_similar.findall(is_paragraph)]
|
||||
uids = [n.uid for n in insert_similar.findall(is_paragraph)] # type: ignore[attr-defined]
|
||||
assert len(new_nodes) == 1
|
||||
assert new_nodes[0].rawsource == 'Anyway I need more' # type: ignore[attr-defined]
|
||||
assert original_uids[0] == uids[0]
|
||||
|
||||
Reference in new issue
Block a user