mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge remote-tracking branch 'upstream/master' into productionlist
# Conflicts: # CHANGES.rst
This commit is contained in:
commit
1f7ed77b2a
@ -27,6 +27,8 @@ Deprecated
|
||||
|
||||
* #13037: Deprecate the ``SingleHTMLBuilder.fix_refuris`` method.
|
||||
Patch by James Addison.
|
||||
* #13083, #13330: Un-deprecate ``sphinx.util.import_object``.
|
||||
Patch by Matthias Geier.
|
||||
|
||||
Features added
|
||||
--------------
|
||||
@ -104,6 +106,8 @@ Features added
|
||||
* #9169: Add the :confval:`intersphinx_resolve_self` option
|
||||
to resolve an intersphinx reference to the current project.
|
||||
Patch by Jakob Lykke Andersen and Adam Turner.
|
||||
* #11280: Add ability to skip a particular section using the ``no-search`` class.
|
||||
Patch by Will Lachance.
|
||||
* #13326: Remove hardcoding from handling :class:`~sphinx.addnodes.productionlist`
|
||||
nodes in all writers, to improve flexibility.
|
||||
Patch by Adam Turner.
|
||||
|
@ -37,11 +37,6 @@ The following is a list of deprecated interfaces.
|
||||
- 10.0
|
||||
- N/A
|
||||
|
||||
* - ``sphinx.util.import_object``
|
||||
- 8.1
|
||||
- 10.0
|
||||
- ``importlib.import_module``
|
||||
|
||||
* - ``sphinx.ext.intersphinx.normalize_intersphinx_mapping``
|
||||
- 8.0
|
||||
- 10.0
|
||||
|
@ -81,7 +81,7 @@ docs = [
|
||||
"sphinxcontrib-websupport",
|
||||
]
|
||||
lint = [
|
||||
"ruff==0.9.5",
|
||||
"ruff==0.9.6",
|
||||
"mypy==1.15.0",
|
||||
"sphinx-lint>=0.9",
|
||||
"types-colorama==0.4.15.20240311",
|
||||
|
@ -11,6 +11,8 @@ __display_version__ = __version__ # used for command line version
|
||||
import os
|
||||
import warnings
|
||||
|
||||
from sphinx.util._pathlib import _StrPath
|
||||
|
||||
# by default, all DeprecationWarning under sphinx package will be emit.
|
||||
# Users can avoid this by using environment variable: PYTHONWARNINGS=
|
||||
if 'PYTHONWARNINGS' not in os.environ:
|
||||
@ -34,7 +36,7 @@ warnings.filterwarnings(
|
||||
#: Before version 1.2, check the string ``sphinx.__version__``.
|
||||
version_info = (8, 2, 0, 'beta', 0)
|
||||
|
||||
package_dir = os.path.abspath(os.path.dirname(__file__))
|
||||
package_dir = _StrPath(__file__).resolve().parent
|
||||
|
||||
_in_development = True
|
||||
if _in_development:
|
||||
|
@ -5,6 +5,7 @@ from __future__ import annotations
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.nodes import document # NoQA: F401
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from collections.abc import Sequence
|
||||
@ -16,22 +17,6 @@ if TYPE_CHECKING:
|
||||
from sphinx.util.typing import ExtensionMetadata
|
||||
|
||||
|
||||
class document(nodes.document):
|
||||
"""The document root element patched by Sphinx.
|
||||
|
||||
This fixes that document.set_id() does not support a node having multiple node Ids.
|
||||
see https://sourceforge.net/p/docutils/patches/167/
|
||||
|
||||
.. important:: This is only for Sphinx internal use. Please don't use this
|
||||
in your extensions. It will be removed without deprecation period.
|
||||
"""
|
||||
|
||||
def set_id(
|
||||
self, node: Element, msgnode: Element | None = None, suggested_prefix: str = ''
|
||||
) -> str:
|
||||
return super().set_id(node, msgnode, suggested_prefix)
|
||||
|
||||
|
||||
class translatable(nodes.Node):
|
||||
"""Node which supports translation.
|
||||
|
||||
|
@ -361,7 +361,7 @@ class Sphinx:
|
||||
|
||||
locale_dirs: list[_StrPath | None] = list(repo.locale_dirs)
|
||||
locale_dirs += [None]
|
||||
locale_dirs += [_StrPath(package_dir, 'locale')]
|
||||
locale_dirs += [package_dir / 'locale']
|
||||
|
||||
self.translator, has_translation = locale.init(
|
||||
locale_dirs, self.config.language
|
||||
|
@ -33,7 +33,7 @@ from sphinx.util.build_phase import BuildPhase
|
||||
from sphinx.util.display import progress_message, status_iterator
|
||||
from sphinx.util.docutils import sphinx_domains
|
||||
from sphinx.util.i18n import CatalogRepository, docname_to_domain
|
||||
from sphinx.util.osutil import canon_path, ensuredir, relative_uri, relpath
|
||||
from sphinx.util.osutil import ensuredir, relative_uri, relpath
|
||||
from sphinx.util.parallel import (
|
||||
ParallelTasks,
|
||||
SerialTasks,
|
||||
@ -518,7 +518,7 @@ class Builder:
|
||||
from sphinx.util.matching import _translate_pattern
|
||||
|
||||
master_doc_path = self.env.doc2path(self.config.master_doc)
|
||||
master_doc_canon = canon_path(master_doc_path)
|
||||
master_doc_canon = master_doc_path.as_posix()
|
||||
for pat in EXCLUDE_PATHS:
|
||||
if not re.match(_translate_pattern(pat), master_doc_canon):
|
||||
continue
|
||||
|
@ -3,7 +3,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import html
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from sphinx import package_dir
|
||||
@ -148,14 +147,14 @@ class ChangesBuilder(Builder):
|
||||
'theme_' + key: val for (key, val) in self.theme.get_options({}).items()
|
||||
}
|
||||
copy_asset_file(
|
||||
Path(package_dir, 'themes', 'default', 'static', 'default.css.jinja'),
|
||||
package_dir.joinpath('themes', 'default', 'static', 'default.css.jinja'),
|
||||
self.outdir,
|
||||
context=themectx,
|
||||
renderer=self.templates,
|
||||
force=True,
|
||||
)
|
||||
copy_asset_file(
|
||||
Path(package_dir, 'themes', 'basic', 'static', 'basic.css'),
|
||||
package_dir.joinpath('themes', 'basic', 'static', 'basic.css'),
|
||||
self.outdir / 'basic.css',
|
||||
force=True,
|
||||
)
|
||||
|
@ -17,7 +17,6 @@ from sphinx.builders import _epub_base
|
||||
from sphinx.config import ENUM
|
||||
from sphinx.locale import __
|
||||
from sphinx.util import logging
|
||||
from sphinx.util._pathlib import _StrPath
|
||||
from sphinx.util.fileutil import copy_asset_file
|
||||
from sphinx.util.osutil import make_filename
|
||||
|
||||
@ -85,7 +84,7 @@ class Epub3Builder(_epub_base.EpubBuilder):
|
||||
epilog = __('The ePub file is in %(outdir)s.')
|
||||
|
||||
supported_remote_images = False
|
||||
template_dir = _StrPath(package_dir, 'templates', 'epub3')
|
||||
template_dir = package_dir.joinpath('templates', 'epub3')
|
||||
doctype = DOCTYPE
|
||||
html_tag = HTML_TAG
|
||||
use_meta_charset = True
|
||||
|
@ -39,7 +39,7 @@ if TYPE_CHECKING:
|
||||
from sphinx.util.i18n import CatalogInfo
|
||||
from sphinx.util.typing import ExtensionMetadata
|
||||
|
||||
DEFAULT_TEMPLATE_PATH = Path(package_dir, 'templates', 'gettext')
|
||||
DEFAULT_TEMPLATE_PATH = package_dir.joinpath('templates', 'gettext')
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
@ -199,8 +199,8 @@ class StandaloneHTMLBuilder(Builder):
|
||||
if js_file.is_file():
|
||||
return js_file
|
||||
|
||||
js_file = Path(
|
||||
package_dir, 'locale', self.config.language, 'LC_MESSAGES', 'sphinx.js'
|
||||
js_file = package_dir.joinpath(
|
||||
'locale', self.config.language, 'LC_MESSAGES', 'sphinx.js'
|
||||
)
|
||||
if js_file.is_file():
|
||||
return js_file
|
||||
|
@ -442,7 +442,7 @@ class LaTeXBuilder(Builder):
|
||||
'xindy_lang_option': xindy_lang_option,
|
||||
'xindy_cyrillic': xindy_cyrillic,
|
||||
}
|
||||
static_dir_name = Path(package_dir, 'texinputs')
|
||||
static_dir_name = package_dir / 'texinputs'
|
||||
for filename in Path(static_dir_name).iterdir():
|
||||
if not filename.name.startswith('.'):
|
||||
copy_asset_file(
|
||||
@ -454,7 +454,7 @@ class LaTeXBuilder(Builder):
|
||||
|
||||
# use pre-1.6.x Makefile for make latexpdf on Windows
|
||||
if os.name == 'nt':
|
||||
static_dir_name = Path(package_dir, 'texinputs_win')
|
||||
static_dir_name = package_dir / 'texinputs_win'
|
||||
copy_asset_file(
|
||||
static_dir_name / 'Makefile.jinja',
|
||||
self.outdir,
|
||||
@ -522,7 +522,7 @@ class LaTeXBuilder(Builder):
|
||||
context['addtocaptions'] = r'\addto\captions%s' % self.babel.get_language()
|
||||
|
||||
copy_asset_file(
|
||||
Path(package_dir, 'templates', 'latex', 'sphinxmessages.sty.jinja'),
|
||||
package_dir.joinpath('templates', 'latex', 'sphinxmessages.sty.jinja'),
|
||||
self.outdir,
|
||||
context=context,
|
||||
renderer=LaTeXRenderer(),
|
||||
|
@ -2,10 +2,8 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import os.path
|
||||
import warnings
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from docutils import nodes
|
||||
@ -36,7 +34,7 @@ if TYPE_CHECKING:
|
||||
from sphinx.util.typing import ExtensionMetadata
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
template_dir = Path(package_dir, 'templates', 'texinfo')
|
||||
template_dir = package_dir.joinpath('templates', 'texinfo')
|
||||
|
||||
|
||||
class TexinfoBuilder(Builder):
|
||||
|
@ -7,6 +7,7 @@ import os
|
||||
import pickle
|
||||
from collections import defaultdict
|
||||
from copy import deepcopy
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from sphinx import addnodes
|
||||
@ -28,7 +29,7 @@ from sphinx.util._timestamps import _format_rfc3339_microseconds
|
||||
from sphinx.util.docutils import LoggingReporter
|
||||
from sphinx.util.i18n import CatalogRepository, docname_to_domain
|
||||
from sphinx.util.nodes import is_translatable
|
||||
from sphinx.util.osutil import _last_modified_time, _relative_path, canon_path
|
||||
from sphinx.util.osutil import _last_modified_time, _relative_path
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from collections.abc import Callable, Iterable, Iterator, Mapping
|
||||
@ -415,7 +416,9 @@ class BuildEnvironment:
|
||||
"""
|
||||
return self.project.doc2path(docname, absolute=base)
|
||||
|
||||
def relfn2path(self, filename: str, docname: str | None = None) -> tuple[str, str]:
|
||||
def relfn2path(
|
||||
self, filename: str | Path, docname: str | None = None
|
||||
) -> tuple[str, str]:
|
||||
"""Return paths to a file referenced from a document, relative to
|
||||
documentation root and absolute.
|
||||
|
||||
@ -423,9 +426,9 @@ class BuildEnvironment:
|
||||
source dir, while relative filenames are relative to the dir of the
|
||||
containing document.
|
||||
"""
|
||||
filename = canon_path(filename)
|
||||
if filename.startswith('/'):
|
||||
abs_fn = (self.srcdir / filename[1:]).resolve()
|
||||
file_name = Path(filename)
|
||||
if file_name.parts[:1] in {('/',), ('\\',)}:
|
||||
abs_fn = self.srcdir.joinpath(*file_name.parts[1:]).resolve()
|
||||
else:
|
||||
if not docname:
|
||||
if self.docname:
|
||||
@ -434,10 +437,10 @@ class BuildEnvironment:
|
||||
msg = 'docname'
|
||||
raise KeyError(msg)
|
||||
doc_dir = self.doc2path(docname, base=False).parent
|
||||
abs_fn = (self.srcdir / doc_dir / filename).resolve()
|
||||
abs_fn = self.srcdir.joinpath(doc_dir, file_name).resolve()
|
||||
|
||||
rel_fn = _relative_path(abs_fn, self.srcdir)
|
||||
return canon_path(rel_fn), os.fspath(abs_fn)
|
||||
return rel_fn.as_posix(), os.fspath(abs_fn)
|
||||
|
||||
@property
|
||||
def found_docs(self) -> set[str]:
|
||||
|
@ -33,7 +33,7 @@ else:
|
||||
|
||||
PY_SUFFIXES = ('.py', '.pyx', *EXTENSION_SUFFIXES)
|
||||
|
||||
template_dir = Path(package_dir, 'templates', 'apidoc')
|
||||
template_dir = package_dir.joinpath('templates', 'apidoc')
|
||||
|
||||
|
||||
def is_initpy(filename: str | Path) -> bool:
|
||||
|
@ -132,7 +132,9 @@ class AutosummaryRenderer:
|
||||
msg = 'Expected a Sphinx application object!'
|
||||
raise TypeError(msg)
|
||||
|
||||
system_templates_path = [Path(package_dir, 'ext', 'autosummary', 'templates')]
|
||||
system_templates_path = [
|
||||
package_dir.joinpath('ext', 'autosummary', 'templates')
|
||||
]
|
||||
loader = SphinxTemplateLoader(
|
||||
app.srcdir, app.config.templates_path, system_templates_path
|
||||
)
|
||||
|
@ -8,7 +8,6 @@ import subprocess
|
||||
import xml.etree.ElementTree as ET
|
||||
from hashlib import sha1
|
||||
from itertools import chain
|
||||
from pathlib import Path
|
||||
from subprocess import CalledProcessError
|
||||
from typing import TYPE_CHECKING
|
||||
from urllib.parse import urlsplit, urlunsplit
|
||||
@ -506,7 +505,7 @@ def man_visit_graphviz(self: ManualPageTranslator, node: graphviz) -> None:
|
||||
|
||||
|
||||
def on_config_inited(_app: Sphinx, config: Config) -> None:
|
||||
css_path = Path(sphinx.package_dir, 'templates', 'graphviz', 'graphviz.css')
|
||||
css_path = sphinx.package_dir.joinpath('templates', 'graphviz', 'graphviz.css')
|
||||
config.html_static_path.append(str(css_path))
|
||||
|
||||
|
||||
|
@ -40,7 +40,7 @@ if TYPE_CHECKING:
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
templates_path = Path(package_dir, 'templates', 'imgmath')
|
||||
templates_path = package_dir.joinpath('templates', 'imgmath')
|
||||
|
||||
|
||||
class MathExtError(SphinxError):
|
||||
|
@ -10,7 +10,6 @@ from docutils.readers import standalone
|
||||
from docutils.transforms.references import DanglingReferences
|
||||
from docutils.writers import UnfilteredWriter
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx.transforms import AutoIndexUpgrader, DoctreeReadEvent, SphinxTransformer
|
||||
from sphinx.transforms.i18n import (
|
||||
Locale,
|
||||
@ -76,7 +75,6 @@ class SphinxBaseReader(standalone.Reader): # type: ignore[misc]
|
||||
for logging.
|
||||
"""
|
||||
document = super().new_document()
|
||||
document.__class__ = addnodes.document # replace the class with patched version
|
||||
|
||||
# substitute transformer
|
||||
document.transformer = SphinxTransformer(document)
|
||||
|
@ -10,7 +10,6 @@ import os
|
||||
import pickle
|
||||
import re
|
||||
from importlib import import_module
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from docutils import nodes
|
||||
@ -39,8 +38,8 @@ if TYPE_CHECKING:
|
||||
def write(self, s: _T_contra, /) -> object: ...
|
||||
|
||||
|
||||
_NON_MINIFIED_JS_PATH = Path(package_dir, 'search', 'non-minified-js')
|
||||
_MINIFIED_JS_PATH = Path(package_dir, 'search', 'minified-js')
|
||||
_NON_MINIFIED_JS_PATH = package_dir.joinpath('search', 'non-minified-js')
|
||||
_MINIFIED_JS_PATH = package_dir.joinpath('search', 'minified-js')
|
||||
|
||||
|
||||
class SearchLanguage:
|
||||
@ -227,6 +226,9 @@ class WordCollector(nodes.NodeVisitor):
|
||||
def dispatch_visit(self, node: Node) -> None:
|
||||
if isinstance(node, nodes.comment):
|
||||
raise nodes.SkipNode
|
||||
elif isinstance(node, nodes.Element) and 'no-search' in node['classes']:
|
||||
# skip nodes marked with a 'no-search' class
|
||||
raise nodes.SkipNode
|
||||
elif isinstance(node, nodes.raw):
|
||||
if 'html' in node.get('format', '').split():
|
||||
# Some people might put content in raw HTML that should be searched,
|
||||
@ -603,6 +605,9 @@ def _feed_visit_nodes(
|
||||
) -> None:
|
||||
if isinstance(node, nodes.comment):
|
||||
return
|
||||
elif isinstance(node, nodes.Element) and 'no-search' in node['classes']:
|
||||
# skip nodes marked with a 'no-search' class
|
||||
return
|
||||
elif isinstance(node, nodes.raw):
|
||||
if 'html' in node.get('format', '').split():
|
||||
# Some people might put content in raw HTML that should be searched,
|
||||
|
@ -159,7 +159,7 @@ class HTMLThemeFactory:
|
||||
|
||||
def _load_builtin_themes(self) -> None:
|
||||
"""Load built-in themes."""
|
||||
themes = self._find_themes(Path(package_dir, 'themes'))
|
||||
themes = self._find_themes(package_dir / 'themes')
|
||||
for name, theme in themes.items():
|
||||
self._themes[name] = _StrPath(theme)
|
||||
|
||||
|
@ -5,10 +5,8 @@ from __future__ import annotations
|
||||
import os
|
||||
import posixpath
|
||||
import re
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from sphinx.errors import FiletypeNotFoundError
|
||||
|
||||
TYPE_CHECKING = False
|
||||
if TYPE_CHECKING:
|
||||
import hashlib
|
||||
from collections.abc import Callable
|
||||
@ -23,12 +21,14 @@ url_re: re.Pattern[str] = re.compile(r'(?P<schema>.+)://.*')
|
||||
|
||||
|
||||
def docname_join(basedocname: str, docname: str) -> str:
|
||||
return posixpath.normpath(posixpath.join('/' + basedocname, '..', docname))[1:]
|
||||
return posixpath.normpath(posixpath.join(f'/{basedocname}', '..', docname))[1:]
|
||||
|
||||
|
||||
def get_filetype(
|
||||
source_suffix: dict[str, str], filename: str | os.PathLike[str]
|
||||
) -> str:
|
||||
from sphinx.errors import FiletypeNotFoundError
|
||||
|
||||
for suffix, filetype in source_suffix.items():
|
||||
if os.fspath(filename).endswith(suffix):
|
||||
# If default filetype (None), considered as restructuredtext.
|
||||
@ -98,12 +98,6 @@ def __getattr__(name: str) -> Any:
|
||||
_deprecation_warning(__name__, name, '', remove=(10, 0))
|
||||
return obj
|
||||
|
||||
if name == 'import_object':
|
||||
from sphinx.util._importer import import_object
|
||||
|
||||
_deprecation_warning(__name__, name, '', remove=(10, 0))
|
||||
return import_object
|
||||
|
||||
# Re-exported for backwards compatibility,
|
||||
# but not currently deprecated
|
||||
|
||||
@ -112,6 +106,11 @@ def __getattr__(name: str) -> Any:
|
||||
|
||||
return encode_uri
|
||||
|
||||
if name == 'import_object':
|
||||
from sphinx.util._importer import import_object
|
||||
|
||||
return import_object
|
||||
|
||||
if name == 'isurl':
|
||||
from sphinx.util._uri import is_url
|
||||
|
||||
|
@ -813,8 +813,6 @@ def new_document(source_path: str, settings: Any = None) -> nodes.document:
|
||||
settings = copy(cached_settings)
|
||||
|
||||
# Create a new instance of nodes.document using cached reporter
|
||||
from sphinx import addnodes
|
||||
|
||||
document = addnodes.document(settings, reporter, source=source_path)
|
||||
document = nodes.document(settings, reporter, source=source_path)
|
||||
document.note_source(source_path, -1)
|
||||
return document
|
||||
|
@ -16,11 +16,7 @@ from sphinx.errors import SphinxError
|
||||
from sphinx.locale import __
|
||||
from sphinx.util import logging
|
||||
from sphinx.util._pathlib import _StrPath
|
||||
from sphinx.util.osutil import (
|
||||
SEP,
|
||||
_last_modified_time,
|
||||
canon_path,
|
||||
)
|
||||
from sphinx.util.osutil import SEP, _last_modified_time
|
||||
|
||||
if TYPE_CHECKING:
|
||||
import datetime as dt
|
||||
@ -163,7 +159,7 @@ class CatalogRepository:
|
||||
@property
|
||||
def catalogs(self) -> Iterator[CatalogInfo]:
|
||||
for basedir, filename in self.pofiles:
|
||||
domain = canon_path(os.path.splitext(filename)[0])
|
||||
domain = filename.with_suffix('').as_posix()
|
||||
yield CatalogInfo(basedir, domain, self.encoding)
|
||||
|
||||
|
||||
|
@ -4,9 +4,9 @@ from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import logging.handlers
|
||||
import os.path
|
||||
from collections import defaultdict
|
||||
from contextlib import contextmanager, nullcontext
|
||||
from os.path import abspath
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from docutils import nodes
|
||||
@ -554,9 +554,9 @@ class WarningLogRecordTranslator(SphinxLogRecordTranslator):
|
||||
def get_node_location(node: Node) -> str | None:
|
||||
source, line = get_source_line(node)
|
||||
if source and line:
|
||||
return f'{abspath(source)}:{line}'
|
||||
return f'{os.path.abspath(source)}:{line}'
|
||||
if source:
|
||||
return f'{abspath(source)}:'
|
||||
return f'{os.path.abspath(source)}:'
|
||||
if line:
|
||||
return f'<unknown>:{line}'
|
||||
return None
|
||||
|
@ -22,7 +22,7 @@ if TYPE_CHECKING:
|
||||
|
||||
from jinja2.environment import Environment
|
||||
|
||||
_TEMPLATES_PATH = Path(package_dir, 'templates')
|
||||
_TEMPLATES_PATH = package_dir / 'templates'
|
||||
_LATEX_TEMPLATES_PATH = _TEMPLATES_PATH / 'latex'
|
||||
|
||||
|
||||
|
@ -89,3 +89,14 @@ def _http_teapot(monkeypatch: pytest.MonkeyPatch) -> Iterator[None]:
|
||||
with monkeypatch.context() as m:
|
||||
m.setattr('sphinx.util.requests._Session.request', _request)
|
||||
yield
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def make_app_with_empty_project(make_app, tmp_path):
|
||||
(tmp_path / 'conf.py').touch()
|
||||
|
||||
def _make_app(*args, **kw):
|
||||
kw.setdefault('srcdir', Path(tmp_path))
|
||||
return make_app(*args, **kw)
|
||||
|
||||
return _make_app
|
||||
|
0
tests/roots/test-_blank/conf.py
Normal file
0
tests/roots/test-_blank/conf.py
Normal file
0
tests/roots/test-_blank/index.rst
Normal file
0
tests/roots/test-_blank/index.rst
Normal file
@ -17,6 +17,10 @@ textinheading
|
||||
|
||||
International
|
||||
|
||||
.. tip::
|
||||
:class: no-search
|
||||
bat cat
|
||||
|
||||
.. toctree::
|
||||
|
||||
tocitem
|
||||
|
@ -2,72 +2,11 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import shutil
|
||||
from contextlib import contextmanager
|
||||
from unittest import mock
|
||||
|
||||
import pytest
|
||||
from docutils import nodes
|
||||
|
||||
from sphinx.cmd.build import build_main
|
||||
from sphinx.errors import SphinxError
|
||||
|
||||
from tests.utils import TESTS_ROOT
|
||||
|
||||
|
||||
def request_session_head(url, **kwargs):
|
||||
response = mock.Mock()
|
||||
response.status_code = 200
|
||||
response.url = url
|
||||
return response
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def nonascii_srcdir(request, rootdir, sphinx_test_tempdir):
|
||||
# Build in a non-ASCII source dir
|
||||
test_name = '\u65e5\u672c\u8a9e'
|
||||
basedir = sphinx_test_tempdir / request.node.originalname
|
||||
srcdir = basedir / test_name
|
||||
if not srcdir.exists():
|
||||
shutil.copytree(rootdir / 'test-root', srcdir)
|
||||
|
||||
# add a doc with a non-ASCII file name to the source dir
|
||||
(srcdir / (test_name + '.txt')).write_text(
|
||||
"""
|
||||
nonascii file name page
|
||||
=======================
|
||||
""",
|
||||
encoding='utf8',
|
||||
)
|
||||
|
||||
root_doc = srcdir / 'index.txt'
|
||||
root_doc.write_text(
|
||||
root_doc.read_text(encoding='utf8')
|
||||
+ f"""
|
||||
.. toctree::
|
||||
|
||||
{test_name}/{test_name}
|
||||
""",
|
||||
encoding='utf8',
|
||||
)
|
||||
return srcdir
|
||||
|
||||
|
||||
# note: this test skips building docs for some builders because they have independent testcase.
|
||||
# (html, changes, epub, latex, texinfo and manpage)
|
||||
@pytest.mark.parametrize(
|
||||
'buildername',
|
||||
['dirhtml', 'singlehtml', 'text', 'xml', 'pseudoxml', 'linkcheck'],
|
||||
)
|
||||
@mock.patch(
|
||||
'sphinx.builders.linkcheck.requests.head',
|
||||
side_effect=request_session_head,
|
||||
)
|
||||
def test_build_all(requests_head, make_app, nonascii_srcdir, buildername):
|
||||
app = make_app(buildername, srcdir=nonascii_srcdir)
|
||||
app.build()
|
||||
|
||||
|
||||
def test_root_doc_not_found(tmp_path, make_app):
|
||||
(tmp_path / 'conf.py').touch()
|
||||
@ -165,29 +104,3 @@ def test_image_glob(app):
|
||||
'image/svg+xml': 'subdir/svgimg.svg',
|
||||
}
|
||||
assert doctree[0][3][0]['uri'] == 'subdir/svgimg.*'
|
||||
|
||||
|
||||
@contextmanager
|
||||
def force_colors():
|
||||
forcecolor = os.environ.get('FORCE_COLOR', None)
|
||||
|
||||
try:
|
||||
os.environ['FORCE_COLOR'] = '1'
|
||||
yield
|
||||
finally:
|
||||
if forcecolor is None:
|
||||
os.environ.pop('FORCE_COLOR', None)
|
||||
else:
|
||||
os.environ['FORCE_COLOR'] = forcecolor
|
||||
|
||||
|
||||
def test_log_no_ansi_colors(tmp_path):
|
||||
with force_colors():
|
||||
wfile = tmp_path / 'warnings.txt'
|
||||
srcdir = TESTS_ROOT / 'roots' / 'test-nitpicky-warnings'
|
||||
argv = list(map(str, ['-b', 'html', srcdir, tmp_path, '-n', '-w', wfile]))
|
||||
retcode = build_main(argv)
|
||||
assert retcode == 0
|
||||
|
||||
content = wfile.read_text(encoding='utf8')
|
||||
assert '\x1b[91m' not in content
|
||||
|
97
tests/test_builders/test_build_all.py
Normal file
97
tests/test_builders/test_build_all.py
Normal file
@ -0,0 +1,97 @@
|
||||
"""Test all builders.
|
||||
|
||||
This test skips building docs for some builders that have independent testcases.
|
||||
(html, changes, epub, latex, texinfo and manpage)
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import shutil
|
||||
from typing import TYPE_CHECKING
|
||||
from unittest import mock
|
||||
|
||||
import pytest
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from collections.abc import Callable
|
||||
from pathlib import Path
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from sphinx.testing.util import SphinxTestApp
|
||||
|
||||
|
||||
def request_session_head(url: str, **kwargs: object) -> mock.Mock:
|
||||
response = mock.Mock()
|
||||
response.status_code = 200
|
||||
response.url = url
|
||||
return response
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def nonascii_srcdir(rootdir: Path, sphinx_test_tempdir: Path) -> Path:
|
||||
# Build in a non-ASCII source dir
|
||||
test_name = '\u65e5\u672c\u8a9e'
|
||||
srcdir = sphinx_test_tempdir / 'test_build_all' / test_name
|
||||
if not srcdir.exists():
|
||||
shutil.copytree(rootdir / 'test-root', srcdir)
|
||||
|
||||
# add a doc with a non-ASCII file name to the source dir
|
||||
(srcdir / f'{test_name}.txt').write_text(
|
||||
'non-ascii file name page\n========================\n', encoding='utf8'
|
||||
)
|
||||
|
||||
with srcdir.joinpath('index.txt').open('a', encoding='utf8') as f:
|
||||
f.write(f"""
|
||||
.. toctree::
|
||||
|
||||
{test_name}/{test_name}
|
||||
""")
|
||||
return srcdir
|
||||
|
||||
|
||||
def test_build_dirhtml(
|
||||
make_app: Callable[..., SphinxTestApp], nonascii_srcdir: Path
|
||||
) -> None:
|
||||
app = make_app('dirhtml', srcdir=nonascii_srcdir)
|
||||
app.build(force_all=True)
|
||||
|
||||
|
||||
def test_build_singlehtml(
|
||||
make_app: Callable[..., SphinxTestApp], nonascii_srcdir: Path
|
||||
) -> None:
|
||||
app = make_app('singlehtml', srcdir=nonascii_srcdir)
|
||||
app.build(force_all=True)
|
||||
|
||||
|
||||
def test_build_text(
|
||||
make_app: Callable[..., SphinxTestApp], nonascii_srcdir: Path
|
||||
) -> None:
|
||||
app = make_app('text', srcdir=nonascii_srcdir)
|
||||
app.build(force_all=True)
|
||||
|
||||
|
||||
def test_build_xml(
|
||||
make_app: Callable[..., SphinxTestApp], nonascii_srcdir: Path
|
||||
) -> None:
|
||||
app = make_app('xml', srcdir=nonascii_srcdir)
|
||||
app.build(force_all=True)
|
||||
|
||||
|
||||
def test_build_pseudoxml(
|
||||
make_app: Callable[..., SphinxTestApp], nonascii_srcdir: Path
|
||||
) -> None:
|
||||
app = make_app('pseudoxml', srcdir=nonascii_srcdir)
|
||||
app.build(force_all=True)
|
||||
|
||||
|
||||
@mock.patch(
|
||||
'sphinx.builders.linkcheck.requests.head',
|
||||
side_effect=request_session_head,
|
||||
)
|
||||
def test_build_linkcheck(
|
||||
requests_head: MagicMock,
|
||||
make_app: Callable[..., SphinxTestApp],
|
||||
nonascii_srcdir: Path,
|
||||
) -> None:
|
||||
app = make_app('linkcheck', srcdir=nonascii_srcdir)
|
||||
app.build(force_all=True)
|
@ -77,20 +77,14 @@ def compile_latex_document(app, filename='projectnamenotset.tex', docclass='manu
|
||||
raise AssertionError(msg) from exc
|
||||
|
||||
|
||||
def skip_if_requested(testfunc):
|
||||
if 'SKIP_LATEX_BUILD' in os.environ:
|
||||
msg = 'Skip LaTeX builds because SKIP_LATEX_BUILD is set'
|
||||
return pytest.mark.skipif(True, reason=msg)(testfunc)
|
||||
else:
|
||||
return testfunc
|
||||
|
||||
|
||||
def skip_if_stylefiles_notfound(testfunc):
|
||||
if kpsetest(*STYLEFILES) is False:
|
||||
msg = 'not running latex, the required styles do not seem to be installed'
|
||||
return pytest.mark.skipif(True, reason=msg)(testfunc)
|
||||
else:
|
||||
return testfunc
|
||||
skip_if_requested = pytest.mark.skipif(
|
||||
'SKIP_LATEX_BUILD' in os.environ,
|
||||
reason='Skip LaTeX builds because SKIP_LATEX_BUILD is set',
|
||||
)
|
||||
skip_if_stylefiles_notfound = pytest.mark.skipif(
|
||||
not kpsetest(*STYLEFILES),
|
||||
reason='not running latex, the required styles do not seem to be installed',
|
||||
)
|
||||
|
||||
|
||||
class RemoteImageHandler(http.server.BaseHTTPRequestHandler):
|
||||
|
@ -4,7 +4,6 @@ from __future__ import annotations
|
||||
|
||||
import pickle
|
||||
from collections import Counter
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING, Any
|
||||
from unittest import mock
|
||||
|
||||
@ -411,17 +410,6 @@ def test_errors_if_setup_is_not_callable(tmp_path, make_app):
|
||||
assert 'callable' in str(excinfo.value)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def make_app_with_empty_project(make_app, tmp_path):
|
||||
(tmp_path / 'conf.py').touch()
|
||||
|
||||
def _make_app(*args, **kw):
|
||||
kw.setdefault('srcdir', Path(tmp_path))
|
||||
return make_app(*args, **kw)
|
||||
|
||||
return _make_app
|
||||
|
||||
|
||||
@mock.patch.object(sphinx, '__display_version__', '1.6.4')
|
||||
def test_needs_sphinx(make_app_with_empty_project):
|
||||
make_app = make_app_with_empty_project
|
||||
|
@ -57,7 +57,7 @@ def test_object_description_sections(app):
|
||||
assert doctree[1][1][0][1][0] == 'Lorem ipsum dolar sit amet'
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_object_description_content_line_number(app):
|
||||
text = '.. py:function:: foo(bar)\n\n Some link here: :ref:`abc`\n'
|
||||
doc = restructuredtext.parse(app, text)
|
||||
|
@ -9,7 +9,7 @@ from sphinx.testing import restructuredtext
|
||||
from sphinx.testing.util import assert_node
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_code_directive(app):
|
||||
# normal case
|
||||
text = '.. code::\n\n print("hello world")\n'
|
||||
@ -89,7 +89,7 @@ def test_csv_table_directive(app):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_math_directive(app):
|
||||
# normal case
|
||||
text = '.. math:: E = mc^2'
|
||||
|
@ -765,7 +765,7 @@ def test_domain_c_build_anon_dup_decl(app):
|
||||
assert 'WARNING: c:identifier reference target not found: @b' in ws[1]
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root', confoverrides={'nitpicky': True})
|
||||
@pytest.mark.sphinx('html', testroot='_blank', confoverrides={'nitpicky': True})
|
||||
def test_domain_c_build_semicolon(app):
|
||||
text = """
|
||||
.. c:member:: int member;
|
||||
@ -875,7 +875,7 @@ _var c:member 1 index.html#c.$ -
|
||||
assert len(ws) == 0
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_domain_c_parse_cfunction(app):
|
||||
text = (
|
||||
'.. c:function:: PyObject* '
|
||||
@ -895,7 +895,7 @@ def test_domain_c_parse_cfunction(app):
|
||||
assert entry == ('index', 'c.PyType_GenericAlloc', 'function')
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_domain_c_parse_cmember(app):
|
||||
text = '.. c:member:: PyObject* PyTypeObject.tp_bases'
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
@ -912,7 +912,7 @@ def test_domain_c_parse_cmember(app):
|
||||
assert entry == ('index', 'c.PyTypeObject.tp_bases', 'member')
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_domain_c_parse_cvar(app):
|
||||
text = '.. c:var:: PyObject* PyClass_Type'
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
@ -929,7 +929,7 @@ def test_domain_c_parse_cvar(app):
|
||||
assert entry == ('index', 'c.PyClass_Type', 'member')
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_domain_c_parse_no_index_entry(app):
|
||||
text = '.. c:function:: void f()\n.. c:function:: void g()\n :no-index-entry:\n'
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
@ -944,7 +944,7 @@ def test_domain_c_parse_no_index_entry(app):
|
||||
|
||||
@pytest.mark.sphinx(
|
||||
'html',
|
||||
testroot='root',
|
||||
testroot='_blank',
|
||||
confoverrides={
|
||||
'c_maximum_signature_line_length': len('str hello(str name)'),
|
||||
},
|
||||
@ -1005,7 +1005,7 @@ def test_cfunction_signature_with_c_maximum_signature_line_length_equal(app):
|
||||
|
||||
@pytest.mark.sphinx(
|
||||
'html',
|
||||
testroot='root',
|
||||
testroot='_blank',
|
||||
confoverrides={
|
||||
'c_maximum_signature_line_length': len('str hello(str name)'),
|
||||
},
|
||||
@ -1066,7 +1066,7 @@ def test_cfunction_signature_with_c_maximum_signature_line_length_force_single(a
|
||||
|
||||
@pytest.mark.sphinx(
|
||||
'html',
|
||||
testroot='root',
|
||||
testroot='_blank',
|
||||
confoverrides={
|
||||
'c_maximum_signature_line_length': len('str hello(str name)'),
|
||||
},
|
||||
@ -1125,7 +1125,7 @@ def test_cfunction_signature_with_c_maximum_signature_line_length_break(app):
|
||||
|
||||
@pytest.mark.sphinx(
|
||||
'html',
|
||||
testroot='root',
|
||||
testroot='_blank',
|
||||
confoverrides={
|
||||
'maximum_signature_line_length': len('str hello(str name)'),
|
||||
},
|
||||
@ -1186,7 +1186,7 @@ def test_cfunction_signature_with_maximum_signature_line_length_equal(app):
|
||||
|
||||
@pytest.mark.sphinx(
|
||||
'html',
|
||||
testroot='root',
|
||||
testroot='_blank',
|
||||
confoverrides={
|
||||
'maximum_signature_line_length': len('str hello(str name)'),
|
||||
},
|
||||
@ -1247,7 +1247,7 @@ def test_cfunction_signature_with_maximum_signature_line_length_force_single(app
|
||||
|
||||
@pytest.mark.sphinx(
|
||||
'html',
|
||||
testroot='root',
|
||||
testroot='_blank',
|
||||
confoverrides={
|
||||
'maximum_signature_line_length': len('str hello(str name)'),
|
||||
},
|
||||
@ -1306,7 +1306,7 @@ def test_cfunction_signature_with_maximum_signature_line_length_break(app):
|
||||
|
||||
@pytest.mark.sphinx(
|
||||
'html',
|
||||
testroot='root',
|
||||
testroot='_blank',
|
||||
confoverrides={
|
||||
'c_maximum_signature_line_length': len('str hello(str name)'),
|
||||
'maximum_signature_line_length': 1,
|
||||
|
@ -1909,7 +1909,7 @@ _var cpp:member 1 index.html#_CPPv44$ -
|
||||
assert len(ws) == 0
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_domain_cpp_parse_no_index_entry(app):
|
||||
text = (
|
||||
'.. cpp:function:: void f()\n.. cpp:function:: void g()\n :no-index-entry:\n'
|
||||
@ -1924,7 +1924,7 @@ def test_domain_cpp_parse_no_index_entry(app):
|
||||
assert_node(doctree[2], addnodes.index, entries=[])
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_domain_cpp_parse_mix_decl_duplicate(app):
|
||||
# Issue 8270
|
||||
text = '.. cpp:struct:: A\n.. cpp:function:: void A()\n.. cpp:struct:: A\n'
|
||||
|
@ -201,7 +201,7 @@ def test_get_full_qualified_name():
|
||||
assert domain.get_full_qualified_name(node) == 'module1.Class.func'
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_js_module(app):
|
||||
text = '.. js:module:: sphinx'
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
@ -214,7 +214,7 @@ def test_js_module(app):
|
||||
assert_node(doctree[1], nodes.target, ids=['module-sphinx'])
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_js_function(app):
|
||||
text = '.. js:function:: sum(a, b)'
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
@ -254,7 +254,7 @@ def test_js_function(app):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_js_class(app):
|
||||
text = '.. js:class:: Application'
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
@ -289,7 +289,7 @@ def test_js_class(app):
|
||||
assert_node(doctree[1], addnodes.desc, domain='js', objtype='class', no_index=False)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_js_data(app):
|
||||
text = '.. js:data:: name'
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
@ -314,7 +314,7 @@ def test_js_data(app):
|
||||
assert_node(doctree[1], addnodes.desc, domain='js', objtype='data', no_index=False)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_no_index_entry(app):
|
||||
text = '.. js:function:: f()\n.. js:function:: g()\n :no-index-entry:\n'
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
@ -346,7 +346,7 @@ def test_no_index_entry(app):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_module_content_line_number(app):
|
||||
text = '.. js:module:: foo\n\n Some link here: :ref:`abc`\n'
|
||||
doc = restructuredtext.parse(app, text)
|
||||
|
@ -344,7 +344,7 @@ def test_get_full_qualified_name():
|
||||
assert domain.get_full_qualified_name(node) == 'module1.Class.func'
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_parse_annotation(app):
|
||||
doctree = _parse_annotation('int', app.env)
|
||||
assert_node(doctree, ([pending_xref, 'int'],))
|
||||
@ -504,7 +504,7 @@ def test_parse_annotation(app):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_parse_annotation_suppress(app):
|
||||
doctree = _parse_annotation('~typing.Dict[str, str]', app.env)
|
||||
assert_node(
|
||||
@ -524,7 +524,7 @@ def test_parse_annotation_suppress(app):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_parse_annotation_Literal(app):
|
||||
doctree = _parse_annotation('Literal[True, False]', app.env)
|
||||
assert_node(
|
||||
@ -814,7 +814,7 @@ def test_modindex_common_prefix(app):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_no_index_entry(app):
|
||||
text = '.. py:function:: f()\n.. py:function:: g()\n :no-index-entry:\n'
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
@ -1209,7 +1209,7 @@ def test_domain_py_python_trailing_comma_in_multi_line_signatures_in_text(app):
|
||||
assert expected_parameter_list_foo in content
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_module_content_line_number(app):
|
||||
text = '.. py:module:: foo\n\n Some link here: :ref:`abc`\n'
|
||||
doc = restructuredtext.parse(app, text)
|
||||
@ -1325,7 +1325,7 @@ def test_short_literal_types(app):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_function_pep_695(app):
|
||||
text = """.. py:function:: func[\
|
||||
S,\
|
||||
@ -1452,7 +1452,7 @@ def test_function_pep_695(app):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_class_def_pep_695(app):
|
||||
# Non-concrete unbound generics are allowed at runtime but type checkers
|
||||
# should fail (https://peps.python.org/pep-0695/#type-parameter-scopes)
|
||||
@ -1508,7 +1508,7 @@ def test_class_def_pep_695(app):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_class_def_pep_696(app):
|
||||
# test default values for type variables without using PEP 696 AST parser
|
||||
text = """.. py:class:: Class[\
|
||||
|
@ -36,7 +36,7 @@ def test_domain_py_canonical(app):
|
||||
assert app.warning.getvalue() == ''
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_canonical(app):
|
||||
text = '.. py:class:: io.StringIO\n :canonical: _io.StringIO'
|
||||
domain = app.env.domains.python_domain
|
||||
@ -69,7 +69,7 @@ def test_canonical(app):
|
||||
assert domain.objects['_io.StringIO'] == ('index', 'io.StringIO', 'class', True)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_canonical_definition_overrides(app):
|
||||
text = (
|
||||
'.. py:class:: io.StringIO\n'
|
||||
@ -83,7 +83,7 @@ def test_canonical_definition_overrides(app):
|
||||
assert domain.objects['_io.StringIO'] == ('index', 'id0', 'class', False)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_canonical_definition_skip(app):
|
||||
text = (
|
||||
'.. py:class:: _io.StringIO\n'
|
||||
@ -98,7 +98,7 @@ def test_canonical_definition_skip(app):
|
||||
assert domain.objects['_io.StringIO'] == ('index', 'io.StringIO', 'class', False)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_canonical_duplicated(app):
|
||||
text = (
|
||||
'.. py:class:: mypackage.StringIO\n'
|
||||
|
@ -22,7 +22,7 @@ from sphinx.testing import restructuredtext
|
||||
from sphinx.testing.util import assert_node
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_info_field_list(app):
|
||||
text = (
|
||||
'.. py:module:: example\n'
|
||||
@ -201,7 +201,7 @@ def test_info_field_list(app):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_info_field_list_piped_type(app):
|
||||
text = (
|
||||
'.. py:module:: example\n'
|
||||
@ -278,7 +278,7 @@ def test_info_field_list_piped_type(app):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_info_field_list_Literal(app):
|
||||
text = (
|
||||
'.. py:module:: example\n'
|
||||
@ -352,7 +352,7 @@ def test_info_field_list_Literal(app):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_info_field_list_var(app):
|
||||
text = '.. py:class:: Class\n\n :var int attr: blah blah\n'
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
@ -391,7 +391,7 @@ def test_info_field_list_var(app):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_info_field_list_napoleon_deliminator_of(app):
|
||||
text = (
|
||||
'.. py:module:: example\n'
|
||||
@ -437,7 +437,7 @@ def test_info_field_list_napoleon_deliminator_of(app):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_info_field_list_napoleon_deliminator_or(app):
|
||||
text = (
|
||||
'.. py:module:: example\n'
|
||||
@ -483,7 +483,7 @@ def test_info_field_list_napoleon_deliminator_or(app):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_type_field(app):
|
||||
text = (
|
||||
'.. py:data:: var1\n'
|
||||
|
@ -28,7 +28,7 @@ from sphinx.testing import restructuredtext
|
||||
from sphinx.testing.util import assert_node
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_pyfunction(app):
|
||||
text = (
|
||||
'.. py:function:: func1\n'
|
||||
@ -99,7 +99,7 @@ def test_pyfunction(app):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_pyfunction_signature(app):
|
||||
text = '.. py:function:: hello(name: str) -> str'
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
@ -146,7 +146,7 @@ def test_pyfunction_signature(app):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_pyfunction_signature_full(app):
|
||||
text = (
|
||||
'.. py:function:: hello(a: str, b = 1, *args: str, '
|
||||
@ -311,7 +311,7 @@ def test_pyfunction_signature_full(app):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_pyfunction_with_unary_operators(app):
|
||||
text = '.. py:function:: menu(egg=+1, bacon=-1, sausage=~1, spam=not spam)'
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
@ -357,7 +357,7 @@ def test_pyfunction_with_unary_operators(app):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_pyfunction_with_binary_operators(app):
|
||||
text = '.. py:function:: menu(spam=2**64)'
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
@ -377,7 +377,7 @@ def test_pyfunction_with_binary_operators(app):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_pyfunction_with_number_literals(app):
|
||||
text = '.. py:function:: hello(age=0x10, height=1_6_0)'
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
@ -407,7 +407,7 @@ def test_pyfunction_with_number_literals(app):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_pyfunction_with_union_type_operator(app):
|
||||
text = '.. py:function:: hello(age: int | None)'
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
@ -437,7 +437,7 @@ def test_pyfunction_with_union_type_operator(app):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_optional_pyfunction_signature(app):
|
||||
text = '.. py:function:: compile(source [, filename [, symbol]]) -> ast object'
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
|
@ -23,7 +23,7 @@ from sphinx.testing import restructuredtext
|
||||
from sphinx.testing.util import assert_node
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_pyexception_signature(app):
|
||||
text = '.. py:exception:: builtins.IOError'
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
@ -60,7 +60,7 @@ def test_pyexception_signature(app):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_pydata_signature(app):
|
||||
text = '.. py:data:: version\n :type: int\n :value: 1\n'
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
@ -109,7 +109,7 @@ def test_pydata_signature(app):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_pydata_signature_old(app):
|
||||
text = '.. py:data:: version\n :annotation: = 1\n'
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
@ -142,7 +142,7 @@ def test_pydata_signature_old(app):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_pydata_with_union_type_operator(app):
|
||||
text = '.. py:data:: version\n :type: int | str'
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
@ -166,7 +166,7 @@ def test_pydata_with_union_type_operator(app):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_pyobject_prefix(app):
|
||||
text = (
|
||||
'.. py:class:: Foo\n\n .. py:method:: Foo.say\n .. py:method:: FooBar.say'
|
||||
@ -200,7 +200,7 @@ def test_pyobject_prefix(app):
|
||||
assert doctree[1][1][3].astext().strip() == 'FooBar.say()'
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_pydata(app):
|
||||
text = '.. py:module:: example\n.. py:data:: var\n :type: int\n'
|
||||
domain = app.env.domains.python_domain
|
||||
@ -239,7 +239,7 @@ def test_pydata(app):
|
||||
assert domain.objects['example.var'] == ('index', 'example.var', 'data', False)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_pyclass_options(app):
|
||||
text = '.. py:class:: Class1\n.. py:class:: Class2\n :final:\n'
|
||||
domain = app.env.domains.python_domain
|
||||
@ -308,7 +308,7 @@ def test_pyclass_options(app):
|
||||
assert domain.objects['Class2'] == ('index', 'Class2', 'class', False)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_pymethod_options(app):
|
||||
text = (
|
||||
'.. py:class:: Class\n'
|
||||
@ -504,7 +504,7 @@ def test_pymethod_options(app):
|
||||
assert domain.objects['Class.meth6'] == ('index', 'Class.meth6', 'method', False)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_pyclassmethod(app):
|
||||
text = '.. py:class:: Class\n\n .. py:classmethod:: meth\n'
|
||||
domain = app.env.domains.python_domain
|
||||
@ -557,7 +557,7 @@ def test_pyclassmethod(app):
|
||||
assert domain.objects['Class.meth'] == ('index', 'Class.meth', 'method', False)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_pystaticmethod(app):
|
||||
text = '.. py:class:: Class\n\n .. py:staticmethod:: meth\n'
|
||||
domain = app.env.domains.python_domain
|
||||
@ -607,7 +607,7 @@ def test_pystaticmethod(app):
|
||||
assert domain.objects['Class.meth'] == ('index', 'Class.meth', 'method', False)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_pyattribute(app):
|
||||
text = (
|
||||
'.. py:class:: Class\n'
|
||||
@ -684,7 +684,7 @@ def test_pyattribute(app):
|
||||
assert domain.objects['Class.attr'] == ('index', 'Class.attr', 'attribute', False)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_pyproperty(app):
|
||||
text = (
|
||||
'.. py:class:: Class\n'
|
||||
@ -795,7 +795,7 @@ def test_pyproperty(app):
|
||||
assert domain.objects['Class.prop2'] == ('index', 'Class.prop2', 'property', False)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_py_type_alias(app):
|
||||
text = (
|
||||
'.. py:module:: example\n'
|
||||
@ -940,7 +940,7 @@ def test_domain_py_type_alias(app):
|
||||
assert app.warning.getvalue() == ''
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_pydecorator_signature(app):
|
||||
text = '.. py:decorator:: deco'
|
||||
domain = app.env.domains.python_domain
|
||||
@ -971,7 +971,7 @@ def test_pydecorator_signature(app):
|
||||
assert domain.objects['deco'] == ('index', 'deco', 'function', False)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_pydecoratormethod_signature(app):
|
||||
text = '.. py:decoratormethod:: deco'
|
||||
domain = app.env.domains.python_domain
|
||||
@ -1002,7 +1002,7 @@ def test_pydecoratormethod_signature(app):
|
||||
assert domain.objects['deco'] == ('index', 'deco', 'method', False)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_pycurrentmodule(app):
|
||||
text = (
|
||||
'.. py:module:: Other\n'
|
||||
|
@ -32,7 +32,7 @@ def test_parse_directive():
|
||||
assert s == ('.. :: bar', '')
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_rst_directive(app):
|
||||
# bare
|
||||
text = '.. rst:directive:: toctree'
|
||||
@ -81,7 +81,7 @@ def test_rst_directive(app):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_rst_directive_with_argument(app):
|
||||
text = '.. rst:directive:: .. toctree:: foo bar baz'
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
@ -115,7 +115,7 @@ def test_rst_directive_with_argument(app):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_rst_directive_option(app):
|
||||
text = '.. rst:directive:option:: foo'
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
@ -142,7 +142,7 @@ def test_rst_directive_option(app):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_rst_directive_option_with_argument(app):
|
||||
text = '.. rst:directive:option:: foo: bar baz'
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
@ -178,7 +178,7 @@ def test_rst_directive_option_with_argument(app):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_rst_directive_option_type(app):
|
||||
text = '.. rst:directive:option:: foo\n :type: directives.flags\n'
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
@ -217,7 +217,7 @@ def test_rst_directive_option_type(app):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_rst_directive_and_directive_option(app):
|
||||
text = '.. rst:directive:: foo\n\n .. rst:directive:option:: bar\n'
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
@ -259,7 +259,7 @@ def test_rst_directive_and_directive_option(app):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_rst_role(app):
|
||||
text = '.. rst:role:: ref'
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
|
@ -89,7 +89,7 @@ def test_get_full_qualified_name():
|
||||
assert domain.get_full_qualified_name(node) == 'ls.-l'
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_cmd_option_with_optional_value(app):
|
||||
text = '.. option:: -j[=N]'
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
@ -116,7 +116,7 @@ def test_cmd_option_with_optional_value(app):
|
||||
assert ('-j', '-j', 'cmdoption', 'index', 'cmdoption-j', 1) in objects
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_cmd_option_starting_with_bracket(app):
|
||||
text = '.. option:: [enable=]PATTERN'
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
@ -147,7 +147,7 @@ def test_cmd_option_starting_with_bracket(app):
|
||||
) in objects
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_glossary(app):
|
||||
text = (
|
||||
'.. glossary::\n'
|
||||
@ -243,7 +243,7 @@ def test_glossary(app):
|
||||
assert_node(refnode, nodes.reference, refid='term-TERM2')
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_glossary_warning(app):
|
||||
# empty line between terms
|
||||
text = '.. glossary::\n\n term1\n\n term2\n'
|
||||
@ -275,7 +275,7 @@ def test_glossary_warning(app):
|
||||
) in app.warning.getvalue()
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_glossary_comment(app):
|
||||
text = (
|
||||
'.. glossary::\n'
|
||||
@ -301,7 +301,7 @@ def test_glossary_comment(app):
|
||||
assert_node(doctree[0][0][0][1], [nodes.definition, nodes.paragraph, 'description'])
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_glossary_comment2(app):
|
||||
text = (
|
||||
'.. glossary::\n'
|
||||
@ -335,7 +335,7 @@ def test_glossary_comment2(app):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_glossary_sorted(app):
|
||||
text = (
|
||||
'.. glossary::\n'
|
||||
@ -373,7 +373,7 @@ def test_glossary_sorted(app):
|
||||
assert_node(doctree[0][0][1][1], [nodes.definition, nodes.paragraph, 'description'])
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_glossary_alphanumeric(app):
|
||||
text = '.. glossary::\n\n 1\n /\n'
|
||||
restructuredtext.parse(app, text)
|
||||
@ -382,7 +382,7 @@ def test_glossary_alphanumeric(app):
|
||||
assert ('/', '/', 'term', 'index', 'term-0', -1) in objects
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_glossary_conflicted_labels(app):
|
||||
text = '.. _term-foo:\n.. glossary::\n\n foo\n'
|
||||
restructuredtext.parse(app, text)
|
||||
@ -390,7 +390,7 @@ def test_glossary_conflicted_labels(app):
|
||||
assert ('foo', 'foo', 'term', 'index', 'term-0', -1) in objects
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_cmdoption(app):
|
||||
text = '.. program:: ls\n\n.. option:: -l\n'
|
||||
domain = app.env.domains.standard_domain
|
||||
@ -417,7 +417,7 @@ def test_cmdoption(app):
|
||||
assert domain.progoptions['ls', '-l'] == ('index', 'cmdoption-ls-l')
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_cmdoption_for_None(app):
|
||||
text = '.. program:: ls\n.. program:: None\n\n.. option:: -l\n'
|
||||
domain = app.env.domains.standard_domain
|
||||
@ -444,7 +444,7 @@ def test_cmdoption_for_None(app):
|
||||
assert domain.progoptions[None, '-l'] == ('index', 'cmdoption-l')
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_multiple_cmdoptions(app):
|
||||
text = '.. program:: cmd\n\n.. option:: -o directory, --output directory\n'
|
||||
domain = app.env.domains.standard_domain
|
||||
@ -485,7 +485,7 @@ def test_multiple_cmdoptions(app):
|
||||
assert domain.progoptions['cmd', '--output'] == ('index', 'cmdoption-cmd-o')
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_disabled_docref(app):
|
||||
text = ':doc:`index`\n:doc:`!index`\n'
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
@ -500,7 +500,7 @@ def test_disabled_docref(app):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_labeled_rubric(app):
|
||||
text = '.. _label:\n.. rubric:: blah *blah* blah\n'
|
||||
restructuredtext.parse(app, text)
|
||||
@ -510,7 +510,7 @@ def test_labeled_rubric(app):
|
||||
assert domain.labels['label'] == ('index', 'label', 'blah blah blah')
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_labeled_definition(app):
|
||||
text = (
|
||||
'.. _label1:\n'
|
||||
@ -533,7 +533,7 @@ def test_labeled_definition(app):
|
||||
assert domain.labels['label2'] == ('index', 'label2', 'Bar blah blah blah')
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_labeled_field(app):
|
||||
text = (
|
||||
'.. _label1:\n'
|
||||
|
@ -17,7 +17,7 @@ def test_ifconfig(app):
|
||||
assert 'ham' not in result
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_ifconfig_content_line_number(app):
|
||||
app.setup_extension('sphinx.ext.ifconfig')
|
||||
text = '.. ifconfig:: confval1\n\n Some link here: :ref:`abc`\n'
|
||||
|
@ -147,15 +147,7 @@ def verify(verify_re_html, verify_re_latex):
|
||||
|
||||
@pytest.fixture
|
||||
def get_verifier(verify, verify_re):
|
||||
v = {
|
||||
'verify': verify,
|
||||
'verify_re': verify_re,
|
||||
}
|
||||
|
||||
def get(name):
|
||||
return v[name]
|
||||
|
||||
return get
|
||||
return {'verify': verify, 'verify_re': verify_re}.__getitem__
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
@ -16,8 +16,8 @@ SPHINX_MODULE_PATH = Path(sphinx.__file__).resolve().with_suffix('.py')
|
||||
|
||||
def test_ModuleAnalyzer_get_module_source():
|
||||
assert ModuleAnalyzer.get_module_source('sphinx') == (
|
||||
sphinx.__file__,
|
||||
sphinx.__loader__.get_source('sphinx'),
|
||||
Path(sphinx.__file__),
|
||||
sphinx.__spec__.loader.get_source('sphinx'),
|
||||
)
|
||||
|
||||
# failed to obtain source information from builtin modules
|
||||
|
@ -398,10 +398,13 @@ def test_nosearch(app):
|
||||
app.build()
|
||||
index = load_searchindex(app.outdir / 'searchindex.js')
|
||||
assert index['docnames'] == ['index', 'nosearch', 'tocitem']
|
||||
# latex is in 'nosearch.rst', and nowhere else
|
||||
assert 'latex' not in index['terms']
|
||||
assert 'bat' in index['terms']
|
||||
# cat is in 'index.rst' but is marked with the 'no-search' class
|
||||
assert 'cat' not in index['terms']
|
||||
# bat is indexed from 'index.rst' and 'tocitem.rst' (document IDs 0, 2), and
|
||||
# not from 'nosearch.rst' (document ID 1)
|
||||
assert 'bat' in index['terms']
|
||||
assert index['terms']['bat'] == [0, 2]
|
||||
|
||||
|
||||
|
@ -10,7 +10,7 @@ from sphinx.testing import restructuredtext
|
||||
from sphinx.testing.util import assert_node
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_transforms_reorder_consecutive_target_and_index_nodes_preserve_order(app):
|
||||
text = '.. index:: abc\n.. index:: def\n.. index:: ghi\n.. index:: jkl\n\ntext\n'
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
@ -47,7 +47,7 @@ def test_transforms_reorder_consecutive_target_and_index_nodes_preserve_order(ap
|
||||
# assert_node(doctree[8], nodes.paragraph)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_transforms_reorder_consecutive_target_and_index_nodes_no_merge_across_other_nodes(
|
||||
app,
|
||||
):
|
||||
@ -98,7 +98,7 @@ def test_transforms_reorder_consecutive_target_and_index_nodes_no_merge_across_o
|
||||
# assert_node(doctree[9], nodes.paragraph)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
@pytest.mark.sphinx('html', testroot='_blank')
|
||||
def test_transforms_reorder_consecutive_target_and_index_nodes_merge_with_labels(app):
|
||||
text = (
|
||||
'.. _abc:\n'
|
||||
|
@ -69,12 +69,11 @@ def test_exported_attributes():
|
||||
assert sphinx.util.FilenameUniqDict is FilenameUniqDict
|
||||
with pytest.warns(RemovedInSphinx10Warning, match=r'deprecated.'):
|
||||
assert sphinx.util.DownloadFiles is DownloadFiles
|
||||
with pytest.warns(RemovedInSphinx10Warning, match=r'deprecated.'):
|
||||
assert sphinx.util.import_object is import_object
|
||||
|
||||
# Re-exported for backwards compatibility,
|
||||
# but not currently deprecated
|
||||
assert sphinx.util.encode_uri is encode_uri
|
||||
assert sphinx.util.import_object is import_object
|
||||
assert sphinx.util.isurl is is_url
|
||||
assert sphinx.util.parselinenos is parse_line_num_spec
|
||||
assert sphinx.util.patfilter is patfilter
|
||||
|
@ -4,17 +4,21 @@ from __future__ import annotations
|
||||
|
||||
import codecs
|
||||
import os
|
||||
from contextlib import contextmanager
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
from docutils import nodes
|
||||
|
||||
from sphinx._cli.util.errors import strip_escape_sequences
|
||||
from sphinx.cmd.build import build_main
|
||||
from sphinx.util import logging
|
||||
from sphinx.util.console import colorize
|
||||
from sphinx.util.logging import is_suppressed_warning, prefixed_warnings
|
||||
from sphinx.util.parallel import ParallelTasks
|
||||
|
||||
from tests.utils import TESTS_ROOT
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
def test_info_and_warning(app):
|
||||
@ -276,6 +280,32 @@ def test_pending_warnings(app):
|
||||
assert 'WARNING: message2\nWARNING: message3' in warnings
|
||||
|
||||
|
||||
@contextmanager
|
||||
def force_colors():
|
||||
forcecolor = os.environ.get('FORCE_COLOR', None)
|
||||
|
||||
try:
|
||||
os.environ['FORCE_COLOR'] = '1'
|
||||
yield
|
||||
finally:
|
||||
if forcecolor is None:
|
||||
os.environ.pop('FORCE_COLOR', None)
|
||||
else:
|
||||
os.environ['FORCE_COLOR'] = forcecolor
|
||||
|
||||
|
||||
def test_log_no_ansi_colors(tmp_path):
|
||||
with force_colors():
|
||||
wfile = tmp_path / 'warnings.txt'
|
||||
srcdir = TESTS_ROOT / 'roots' / 'test-nitpicky-warnings'
|
||||
argv = list(map(str, ['-b', 'html', srcdir, tmp_path, '-n', '-w', wfile]))
|
||||
retcode = build_main(argv)
|
||||
assert retcode == 0
|
||||
|
||||
content = wfile.read_text(encoding='utf8')
|
||||
assert '\x1b[91m' not in content
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
def test_colored_logs(app):
|
||||
app.verbosity = 2
|
||||
|
Loading…
Reference in New Issue
Block a user