mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
[lint] whitelist all test files except configuration and utils in tests (#12109)
This commit is contained in:
151
pyproject.toml
151
pyproject.toml
@@ -131,7 +131,8 @@ exclude = [
|
||||
]
|
||||
|
||||
[tool.mypy]
|
||||
files = ["sphinx", "utils"]
|
||||
files = ["sphinx", "utils", "tests"]
|
||||
exclude = ["tests/certs", "tests/js", "tests/roots"]
|
||||
check_untyped_defs = true
|
||||
disallow_incomplete_defs = true
|
||||
python_version = "3.9"
|
||||
@@ -212,6 +213,154 @@ module = [
|
||||
]
|
||||
disallow_any_generics = false
|
||||
|
||||
[[tool.mypy.overrides]]
|
||||
module = [
|
||||
# tests/
|
||||
# "tests.conftest",
|
||||
"tests.test_addnodes",
|
||||
"tests.test_application",
|
||||
"tests.test_errors",
|
||||
"tests.test_events",
|
||||
"tests.test_highlighting",
|
||||
"tests.test_project",
|
||||
"tests.test_quickstart",
|
||||
"tests.test_roles",
|
||||
"tests.test_search",
|
||||
"tests.test_toctree",
|
||||
"tests.test_versioning",
|
||||
# "tests.utils",
|
||||
# tests/test_builders
|
||||
# "tests.test_builders.conftest",
|
||||
"tests.test_builders.test_build",
|
||||
"tests.test_builders.test_build_changes",
|
||||
"tests.test_builders.test_build_dirhtml",
|
||||
"tests.test_builders.test_build_epub",
|
||||
"tests.test_builders.test_builder",
|
||||
"tests.test_builders.test_build_gettext",
|
||||
"tests.test_builders.test_build_html",
|
||||
"tests.test_builders.test_build_html_5_output",
|
||||
"tests.test_builders.test_build_html_assets",
|
||||
"tests.test_builders.test_build_html_code",
|
||||
"tests.test_builders.test_build_html_download",
|
||||
"tests.test_builders.test_build_html_highlight",
|
||||
"tests.test_builders.test_build_html_image",
|
||||
"tests.test_builders.test_build_html_maths",
|
||||
"tests.test_builders.test_build_html_numfig",
|
||||
"tests.test_builders.test_build_html_tocdepth",
|
||||
"tests.test_builders.test_build_latex",
|
||||
"tests.test_builders.test_build_linkcheck",
|
||||
"tests.test_builders.test_build_manpage",
|
||||
"tests.test_builders.test_build_texinfo",
|
||||
"tests.test_builders.test_build_text",
|
||||
"tests.test_builders.test_build_warnings",
|
||||
# tests/test_config
|
||||
"tests.test_config.test_config",
|
||||
"tests.test_config.test_correct_year",
|
||||
# tests/test_directives
|
||||
"tests.test_directives.test_directive_code",
|
||||
"tests.test_directives.test_directive_object_description",
|
||||
"tests.test_directives.test_directive_only",
|
||||
"tests.test_directives.test_directive_option",
|
||||
"tests.test_directives.test_directive_other",
|
||||
"tests.test_directives.test_directive_patch",
|
||||
"tests.test_directives.test_directives_no_typesetting",
|
||||
# tests/test_domains
|
||||
"tests.test_domains.test_domain_c",
|
||||
"tests.test_domains.test_domain_cpp",
|
||||
"tests.test_domains.test_domain_js",
|
||||
"tests.test_domains.test_domain_py",
|
||||
"tests.test_domains.test_domain_py_canonical",
|
||||
"tests.test_domains.test_domain_py_fields",
|
||||
"tests.test_domains.test_domain_py_pyfunction",
|
||||
"tests.test_domains.test_domain_py_pyobject",
|
||||
"tests.test_domains.test_domain_rst",
|
||||
"tests.test_domains.test_domain_std",
|
||||
# tests/test_environment
|
||||
"tests.test_environment.test_environment",
|
||||
"tests.test_environment.test_environment_indexentries",
|
||||
"tests.test_environment.test_environment_record_dependencies",
|
||||
"tests.test_environment.test_environment_toctree",
|
||||
# tests/test_extensions
|
||||
"tests.test_extensions.ext_napoleon_pep526_data_google",
|
||||
"tests.test_extensions.ext_napoleon_pep526_data_numpy",
|
||||
"tests.test_extensions.test_ext_apidoc",
|
||||
"tests.test_extensions.test_ext_autodoc",
|
||||
"tests.test_extensions.test_ext_autodoc_autoattribute",
|
||||
"tests.test_extensions.test_ext_autodoc_autoclass",
|
||||
"tests.test_extensions.test_ext_autodoc_autodata",
|
||||
"tests.test_extensions.test_ext_autodoc_autofunction",
|
||||
"tests.test_extensions.test_ext_autodoc_automodule",
|
||||
"tests.test_extensions.test_ext_autodoc_autoproperty",
|
||||
"tests.test_extensions.test_ext_autodoc_configs",
|
||||
"tests.test_extensions.test_ext_autodoc_events",
|
||||
"tests.test_extensions.test_ext_autodoc_mock",
|
||||
"tests.test_extensions.test_ext_autodoc_preserve_defaults",
|
||||
"tests.test_extensions.test_ext_autodoc_private_members",
|
||||
"tests.test_extensions.test_ext_autosectionlabel",
|
||||
"tests.test_extensions.test_ext_autosummary",
|
||||
"tests.test_extensions.test_ext_coverage",
|
||||
"tests.test_extensions.test_ext_doctest",
|
||||
"tests.test_extensions.test_ext_duration",
|
||||
"tests.test_extensions.test_extension",
|
||||
"tests.test_extensions.test_ext_extlinks",
|
||||
"tests.test_extensions.test_ext_githubpages",
|
||||
"tests.test_extensions.test_ext_graphviz",
|
||||
"tests.test_extensions.test_ext_ifconfig",
|
||||
"tests.test_extensions.test_ext_imgconverter",
|
||||
"tests.test_extensions.test_ext_imgmockconverter",
|
||||
"tests.test_extensions.test_ext_inheritance_diagram",
|
||||
"tests.test_extensions.test_ext_intersphinx",
|
||||
"tests.test_extensions.test_ext_math",
|
||||
"tests.test_extensions.test_ext_napoleon",
|
||||
"tests.test_extensions.test_ext_napoleon_docstring",
|
||||
"tests.test_extensions.test_ext_todo",
|
||||
"tests.test_extensions.test_ext_viewcode",
|
||||
# tests/test_intl
|
||||
"tests.test_intl.test_catalogs",
|
||||
"tests.test_intl.test_intl",
|
||||
"tests.test_intl.test_locale",
|
||||
# tests/test_markup
|
||||
"tests.test_markup.test_markup",
|
||||
"tests.test_markup.test_metadata",
|
||||
"tests.test_markup.test_parser",
|
||||
"tests.test_markup.test_smartquotes",
|
||||
# tests/test_pycode
|
||||
"tests.test_pycode.test_pycode",
|
||||
"tests.test_pycode.test_pycode_ast",
|
||||
"tests.test_pycode.test_pycode_parser",
|
||||
# tests/test_theming
|
||||
"tests.test_theming.test_html_theme",
|
||||
"tests.test_theming.test_templating",
|
||||
"tests.test_theming.test_theming",
|
||||
# tests/test_transforms
|
||||
"tests.test_transforms.test_transforms_move_module_targets",
|
||||
"tests.test_transforms.test_transforms_post_transforms",
|
||||
"tests.test_transforms.test_transforms_post_transforms_code",
|
||||
"tests.test_transforms.test_transforms_reorder_nodes",
|
||||
# tests/test_util
|
||||
"tests.test_util.test_util",
|
||||
"tests.test_util.test_util_display",
|
||||
"tests.test_util.test_util_docstrings",
|
||||
"tests.test_util.test_util_docutils",
|
||||
"tests.test_util.test_util_fileutil",
|
||||
"tests.test_util.test_util_i18n",
|
||||
"tests.test_util.test_util_images",
|
||||
"tests.test_util.test_util_inspect",
|
||||
"tests.test_util.test_util_inventory",
|
||||
"tests.test_util.test_util_logging",
|
||||
"tests.test_util.test_util_matching",
|
||||
"tests.test_util.test_util_nodes",
|
||||
"tests.test_util.test_util_rst",
|
||||
"tests.test_util.test_util_template",
|
||||
"tests.test_util.test_util_typing",
|
||||
"tests.test_util.typing_test_data",
|
||||
# tests/test_writers
|
||||
"tests.test_writers.test_api_translator",
|
||||
"tests.test_writers.test_docutilsconf",
|
||||
"tests.test_writers.test_writer_latex",
|
||||
]
|
||||
ignore_errors = true
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
minversion = 6.0
|
||||
addopts = [
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import docutils
|
||||
import pytest
|
||||
@@ -10,8 +13,13 @@ import sphinx.locale
|
||||
import sphinx.pycode
|
||||
from sphinx.testing.util import _clean_up_global_state
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from collections.abc import Generator
|
||||
|
||||
def _init_console(locale_dir=sphinx.locale._LOCALE_DIR, catalog='sphinx'):
|
||||
|
||||
def _init_console(
|
||||
locale_dir: str | None = sphinx.locale._LOCALE_DIR, catalog: str = 'sphinx',
|
||||
) -> tuple[sphinx.locale.NullTranslations, bool]:
|
||||
"""Monkeypatch ``init_console`` to skip its action.
|
||||
|
||||
Some tests rely on warning messages in English. We don't want
|
||||
@@ -23,7 +31,7 @@ def _init_console(locale_dir=sphinx.locale._LOCALE_DIR, catalog='sphinx'):
|
||||
|
||||
sphinx.locale.init_console = _init_console
|
||||
|
||||
pytest_plugins = 'sphinx.testing.fixtures'
|
||||
pytest_plugins = ['sphinx.testing.fixtures']
|
||||
|
||||
# Exclude 'roots' dirs for pytest test collector
|
||||
collect_ignore = ['roots']
|
||||
@@ -32,11 +40,11 @@ os.environ['SPHINX_AUTODOC_RELOAD_MODULES'] = '1'
|
||||
|
||||
|
||||
@pytest.fixture(scope='session')
|
||||
def rootdir():
|
||||
def rootdir() -> Path:
|
||||
return Path(__file__).parent.resolve() / 'roots'
|
||||
|
||||
|
||||
def pytest_report_header(config):
|
||||
def pytest_report_header(config: pytest.Config) -> str:
|
||||
header = f"libraries: Sphinx-{sphinx.__display_version__}, docutils-{docutils.__version__}"
|
||||
if hasattr(config, '_tmp_path_factory'):
|
||||
header += f"\nbase tmp_path: {config._tmp_path_factory.getbasetemp()}"
|
||||
@@ -44,7 +52,7 @@ def pytest_report_header(config):
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def _cleanup_docutils():
|
||||
def _cleanup_docutils() -> Generator[None, None, None]:
|
||||
saved_path = sys.path
|
||||
yield # run the test
|
||||
sys.path[:] = saved_path
|
||||
|
||||
@@ -6,12 +6,14 @@ import pytest
|
||||
from html5lib import HTMLParser
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from collections.abc import Callable, Generator
|
||||
from pathlib import Path
|
||||
from xml.etree.ElementTree import Element
|
||||
|
||||
etree_cache = {}
|
||||
etree_cache: dict[Path, Element] = {}
|
||||
|
||||
|
||||
def _parse(fname: Path) -> HTMLParser:
|
||||
def _parse(fname: Path) -> Element:
|
||||
if fname in etree_cache:
|
||||
return etree_cache[fname]
|
||||
with fname.open('rb') as fp:
|
||||
@@ -21,6 +23,6 @@ def _parse(fname: Path) -> HTMLParser:
|
||||
|
||||
|
||||
@pytest.fixture(scope='package')
|
||||
def cached_etree_parse():
|
||||
def cached_etree_parse() -> Generator[Callable[[Path], Element], None, None]:
|
||||
yield _parse
|
||||
etree_cache.clear()
|
||||
|
||||
@@ -1,54 +1,71 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import contextlib
|
||||
import http.server
|
||||
import pathlib
|
||||
import threading
|
||||
from http.server import ThreadingHTTPServer
|
||||
from pathlib import Path
|
||||
from ssl import PROTOCOL_TLS_SERVER, SSLContext
|
||||
from threading import Thread
|
||||
from typing import TYPE_CHECKING, TypeVar
|
||||
|
||||
import filelock
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from collections.abc import Callable, Generator
|
||||
from contextlib import AbstractContextManager
|
||||
from socketserver import BaseRequestHandler
|
||||
from typing import Any, Final
|
||||
|
||||
# Generated with:
|
||||
# $ openssl req -new -x509 -days 3650 -nodes -out cert.pem \
|
||||
# -keyout cert.pem -addext "subjectAltName = DNS:localhost"
|
||||
TESTS_ROOT = pathlib.Path(__file__).parent
|
||||
CERT_FILE = str(TESTS_ROOT / "certs" / "cert.pem")
|
||||
TESTS_ROOT: Final[Path] = Path(__file__).parent
|
||||
CERT_FILE: Final[str] = str(TESTS_ROOT / "certs" / "cert.pem")
|
||||
|
||||
# File lock for tests
|
||||
LOCK_PATH = str(TESTS_ROOT / 'test-server.lock')
|
||||
LOCK_PATH: Final[str] = str(TESTS_ROOT / 'test-server.lock')
|
||||
|
||||
|
||||
class HttpServerThread(threading.Thread):
|
||||
def __init__(self, handler, *args, **kwargs):
|
||||
class HttpServerThread(Thread):
|
||||
def __init__(self, handler: type[BaseRequestHandler], /, *args: Any, **kwargs: Any) -> None:
|
||||
super().__init__(*args, **kwargs)
|
||||
self.server = http.server.ThreadingHTTPServer(("localhost", 7777), handler)
|
||||
self.server = ThreadingHTTPServer(("localhost", 7777), handler)
|
||||
|
||||
def run(self):
|
||||
def run(self) -> None:
|
||||
self.server.serve_forever(poll_interval=0.001)
|
||||
|
||||
def terminate(self):
|
||||
def terminate(self) -> None:
|
||||
self.server.shutdown()
|
||||
self.server.server_close()
|
||||
self.join()
|
||||
|
||||
|
||||
class HttpsServerThread(HttpServerThread):
|
||||
def __init__(self, handler, *args, **kwargs):
|
||||
def __init__(
|
||||
self, handler: type[BaseRequestHandler], /, *args: Any, **kwargs: Any,
|
||||
) -> None:
|
||||
super().__init__(handler, *args, **kwargs)
|
||||
sslcontext = SSLContext(PROTOCOL_TLS_SERVER)
|
||||
sslcontext.load_cert_chain(CERT_FILE)
|
||||
self.server.socket = sslcontext.wrap_socket(self.server.socket, server_side=True)
|
||||
|
||||
|
||||
def create_server(thread_class):
|
||||
def server(handler):
|
||||
_T_co = TypeVar('_T_co', bound=HttpServerThread, covariant=True)
|
||||
|
||||
|
||||
def create_server(
|
||||
server_thread_class: type[_T_co],
|
||||
) -> Callable[[type[BaseRequestHandler]], AbstractContextManager[_T_co]]:
|
||||
@contextlib.contextmanager
|
||||
def server(handler_class: type[BaseRequestHandler]) -> Generator[_T_co, None, None]:
|
||||
lock = filelock.FileLock(LOCK_PATH)
|
||||
with lock:
|
||||
server_thread = thread_class(handler, daemon=True)
|
||||
server_thread = server_thread_class(handler_class, daemon=True)
|
||||
server_thread.start()
|
||||
try:
|
||||
yield server_thread
|
||||
finally:
|
||||
server_thread.terminate()
|
||||
return contextlib.contextmanager(server)
|
||||
return server
|
||||
|
||||
|
||||
http_server = create_server(HttpServerThread)
|
||||
|
||||
Reference in New Issue
Block a user