mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2026-10-31 17:17:43 -05:00
Avoid attribute indirection with `env` (#13212)
This commit is contained in:
1 parent
56c9e32fbc
commit
83bf866059
42 files changed
+181
-160
No files matched your search
@@ -76,7 +76,7 @@ def process_todo_nodes(app, doctree, fromdocname):
|
||||
|
||||
# Replace all todolist nodes with a list of the collected todos.
|
||||
# Augment each todo with a backlink to the original location.
|
||||
env = app.builder.env
|
||||
env = app.env
|
||||
|
||||
if not hasattr(env, 'todo_all_todos'):
|
||||
env.todo_all_todos = []
|
||||
|
||||
@@ -48,6 +48,7 @@ from sphinx import roles # NoQA: F401 isort:skip
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from collections.abc import Iterable, Sequence, Set
|
||||
from pathlib import Path
|
||||
|
||||
from docutils.nodes import Node
|
||||
|
||||
@@ -242,8 +243,8 @@ class Builder:
|
||||
if not self.config.gettext_auto_build:
|
||||
return
|
||||
|
||||
def cat2relpath(cat: CatalogInfo) -> str:
|
||||
return relpath(cat.mo_path, self.env.srcdir).replace(os.path.sep, SEP)
|
||||
def cat2relpath(cat: CatalogInfo, srcdir: Path = self.srcdir) -> str:
|
||||
return relpath(cat.mo_path, srcdir).replace(os.path.sep, SEP)
|
||||
|
||||
logger.info(bold(__('building [mo]: ')) + message)
|
||||
for catalog in status_iterator(
|
||||
@@ -615,14 +616,15 @@ class Builder:
|
||||
@final
|
||||
def read_doc(self, docname: str, *, _cache: bool = True) -> None:
|
||||
"""Parse a file and add/update inventory entries for the doctree."""
|
||||
self.env.prepare_settings(docname)
|
||||
env = self.env
|
||||
env.prepare_settings(docname)
|
||||
|
||||
# Add confdir/docutils.conf to dependencies list if exists
|
||||
docutilsconf = os.path.join(self.confdir, 'docutils.conf')
|
||||
if os.path.isfile(docutilsconf):
|
||||
self.env.note_dependency(docutilsconf)
|
||||
env.note_dependency(docutilsconf)
|
||||
|
||||
filename = str(self.env.doc2path(docname))
|
||||
filename = str(env.doc2path(docname))
|
||||
filetype = get_filetype(self.app.config.source_suffix, filename)
|
||||
publisher = self.app.registry.get_publisher(self.app, filetype)
|
||||
self.env.current_document._parser = publisher.parser
|
||||
@@ -630,7 +632,7 @@ class Builder:
|
||||
# explicitly re-initialise for each document
|
||||
publisher.settings.record_dependencies = DependencyList()
|
||||
with (
|
||||
sphinx_domains(self.env),
|
||||
sphinx_domains(env),
|
||||
rst.default_role(docname, self.config.default_role),
|
||||
):
|
||||
# set up error_handler for the target document
|
||||
@@ -642,11 +644,11 @@ class Builder:
|
||||
doctree = publisher.document
|
||||
|
||||
# store time of reading, for outdated files detection
|
||||
self.env.all_docs[docname] = time.time_ns() // 1_000
|
||||
env.all_docs[docname] = time.time_ns() // 1_000
|
||||
|
||||
# cleanup
|
||||
self.env.current_document = _CurrentDocument()
|
||||
self.env.ref_context.clear()
|
||||
env.current_document = _CurrentDocument()
|
||||
env.ref_context.clear()
|
||||
|
||||
self.write_doctree(docname, doctree, _cache=_cache)
|
||||
|
||||
|
||||
@@ -128,7 +128,7 @@ class ChangesBuilder(Builder):
|
||||
logger.info(bold(__('copying source files...')))
|
||||
for docname in self.env.all_docs:
|
||||
with open(
|
||||
self.env.doc2path(docname), encoding=self.env.config.source_encoding
|
||||
self.env.doc2path(docname), encoding=self.config.source_encoding
|
||||
) as f:
|
||||
try:
|
||||
lines = f.readlines()
|
||||
|
||||
@@ -146,10 +146,8 @@ class I18nBuilder(Builder):
|
||||
|
||||
def init(self) -> None:
|
||||
super().init()
|
||||
self.env.set_versioning_method(
|
||||
self.versioning_method, self.env.config.gettext_uuid
|
||||
)
|
||||
self.tags = I18nTags()
|
||||
self.env.set_versioning_method(self.versioning_method, self.config.gettext_uuid)
|
||||
self.tags = self.app.tags = I18nTags()
|
||||
self.catalogs: defaultdict[str, Catalog] = defaultdict(Catalog)
|
||||
|
||||
def get_target_uri(self, docname: str, typ: str | None = None) -> str:
|
||||
@@ -174,7 +172,7 @@ class I18nBuilder(Builder):
|
||||
if not _is_node_in_substitution_definition(node):
|
||||
catalog.add(msg, node)
|
||||
|
||||
if 'index' in self.env.config.gettext_additional_targets:
|
||||
if 'index' in self.config.gettext_additional_targets:
|
||||
# Extract translatable messages from index entries.
|
||||
for node, entries in traverse_translatable_index(doctree):
|
||||
for entry_type, value, _target_id, _main, _category_key in entries:
|
||||
|
||||
@@ -771,7 +771,7 @@ class StandaloneHTMLBuilder(Builder):
|
||||
|
||||
def copy_image_files(self) -> None:
|
||||
if self.images:
|
||||
stringify_func = ImageAdapter(self.app.env).get_original_image_uri
|
||||
stringify_func = ImageAdapter(self.env).get_original_image_uri
|
||||
ensuredir(self._images_dir)
|
||||
for src in status_iterator(
|
||||
self.images,
|
||||
|
||||
@@ -476,7 +476,7 @@ class LaTeXBuilder(Builder):
|
||||
|
||||
def copy_image_files(self) -> None:
|
||||
if self.images:
|
||||
stringify_func = ImageAdapter(self.app.env).get_original_image_uri
|
||||
stringify_func = ImageAdapter(self.env).get_original_image_uri
|
||||
for src in status_iterator(
|
||||
self.images,
|
||||
__('copying images... '),
|
||||
|
||||
@@ -196,7 +196,7 @@ class TexinfoBuilder(Builder):
|
||||
|
||||
def copy_image_files(self, targetname: str) -> None:
|
||||
if self.images:
|
||||
stringify_func = ImageAdapter(self.app.env).get_original_image_uri
|
||||
stringify_func = ImageAdapter(self.env).get_original_image_uri
|
||||
for src in status_iterator(
|
||||
self.images,
|
||||
__('copying images... '),
|
||||
|
||||
@@ -267,7 +267,7 @@ class ObjectDescription(SphinxDirective, Generic[ObjDescT]):
|
||||
finally:
|
||||
# Private attributes for ToC generation. Will be modified or removed
|
||||
# without notice.
|
||||
if self.env.config.toc_object_entries:
|
||||
if self.config.toc_object_entries:
|
||||
signode['_toc_parts'] = self._object_hierarchy_parts(signode)
|
||||
signode['_toc_name'] = self._toc_entry_name(signode)
|
||||
else:
|
||||
|
||||
@@ -107,6 +107,7 @@ class Domain:
|
||||
data_version = 0
|
||||
|
||||
def __init__(self, env: BuildEnvironment) -> None:
|
||||
domain_data: dict[str, dict[str, Any]] = env.domaindata
|
||||
self.env: BuildEnvironment = env
|
||||
self._role_cache: dict[str, RoleFunction] = {}
|
||||
self._directive_cache: dict[str, type[Directive]] = {}
|
||||
@@ -119,13 +120,13 @@ class Domain:
|
||||
self.roles = dict(self.roles)
|
||||
self.indices = list(self.indices)
|
||||
|
||||
if self.name not in env.domaindata:
|
||||
if self.name not in domain_data:
|
||||
assert isinstance(self.initial_data, dict)
|
||||
new_data = copy.deepcopy(self.initial_data)
|
||||
new_data['version'] = self.data_version
|
||||
self.data = env.domaindata[self.name] = new_data
|
||||
self.data = domain_data[self.name] = new_data
|
||||
else:
|
||||
self.data = env.domaindata[self.name]
|
||||
self.data = domain_data[self.name]
|
||||
if self.data['version'] != self.data_version:
|
||||
raise OSError('data of %r domain out of date' % self.label)
|
||||
for name, obj in self.object_types.items():
|
||||
|
||||
@@ -219,7 +219,7 @@ class CObject(ObjectDescription[ASTDeclaration]):
|
||||
ast.describe_signature(signode, 'lastIsName', self.env, options)
|
||||
|
||||
def run(self) -> list[Node]:
|
||||
env = self.state.document.settings.env # from ObjectDescription.run
|
||||
env = self.env
|
||||
if env.current_document.c_parent_symbol is None:
|
||||
root = env.domaindata['c']['root_symbol']
|
||||
env.current_document.c_parent_symbol = root
|
||||
@@ -235,8 +235,8 @@ class CObject(ObjectDescription[ASTDeclaration]):
|
||||
parent_symbol: Symbol = self.env.current_document.c_parent_symbol
|
||||
|
||||
max_len = (
|
||||
self.env.config.c_maximum_signature_line_length
|
||||
or self.env.config.maximum_signature_line_length
|
||||
self.config.c_maximum_signature_line_length
|
||||
or self.config.maximum_signature_line_length
|
||||
or 0
|
||||
)
|
||||
signode['multi_line_parameter_list'] = (
|
||||
@@ -244,7 +244,7 @@ class CObject(ObjectDescription[ASTDeclaration]):
|
||||
and (len(sig) > max_len > 0)
|
||||
)
|
||||
|
||||
parser = DefinitionParser(sig, location=signode, config=self.env.config)
|
||||
parser = DefinitionParser(sig, location=signode, config=self.config)
|
||||
try:
|
||||
ast = self.parse_definition(parser)
|
||||
parser.assert_end()
|
||||
@@ -400,7 +400,7 @@ class CNamespaceObject(SphinxDirective):
|
||||
stack: list[Symbol] = []
|
||||
else:
|
||||
parser = DefinitionParser(
|
||||
self.arguments[0], location=self.get_location(), config=self.env.config
|
||||
self.arguments[0], location=self.get_location(), config=self.config
|
||||
)
|
||||
try:
|
||||
name = parser.parse_namespace_object()
|
||||
@@ -427,7 +427,7 @@ class CNamespacePushObject(SphinxDirective):
|
||||
if self.arguments[0].strip() in {'NULL', '0', 'nullptr'}:
|
||||
return []
|
||||
parser = DefinitionParser(
|
||||
self.arguments[0], location=self.get_location(), config=self.env.config
|
||||
self.arguments[0], location=self.get_location(), config=self.config
|
||||
)
|
||||
try:
|
||||
name = parser.parse_namespace_object()
|
||||
@@ -567,7 +567,7 @@ class AliasTransform(SphinxTransform):
|
||||
sig = node.sig
|
||||
parent_key = node.parentKey
|
||||
try:
|
||||
parser = DefinitionParser(sig, location=node, config=self.env.config)
|
||||
parser = DefinitionParser(sig, location=node, config=self.config)
|
||||
name = parser.parse_xref_object()
|
||||
except DefinitionError as e:
|
||||
logger.warning(e, location=node)
|
||||
@@ -716,7 +716,7 @@ class CExprRole(SphinxRole):
|
||||
def run(self) -> tuple[list[Node], list[system_message]]:
|
||||
text = self.text.replace('\n', ' ')
|
||||
parser = DefinitionParser(
|
||||
text, location=self.get_location(), config=self.env.config
|
||||
text, location=self.get_location(), config=self.config
|
||||
)
|
||||
# attempt to mimic XRefRole classes, except that...
|
||||
try:
|
||||
|
||||
@@ -259,7 +259,7 @@ class CPPObject(ObjectDescription[ASTDeclaration]):
|
||||
break
|
||||
if not is_in_concept and 'no-index-entry' not in self.options:
|
||||
stripped_name = name
|
||||
for prefix in self.env.config.cpp_index_common_prefix:
|
||||
for prefix in self.config.cpp_index_common_prefix:
|
||||
if name.startswith(prefix):
|
||||
stripped_name = stripped_name[len(prefix) :]
|
||||
break
|
||||
@@ -308,7 +308,7 @@ class CPPObject(ObjectDescription[ASTDeclaration]):
|
||||
ast.describe_signature(signode, 'lastIsName', self.env, options)
|
||||
|
||||
def run(self) -> list[Node]:
|
||||
env = self.state.document.settings.env # from ObjectDescription.run
|
||||
env = self.env
|
||||
if env.current_document.cpp_parent_symbol is None:
|
||||
root = env.domaindata['cpp']['root_symbol']
|
||||
env.current_document.cpp_parent_symbol = root
|
||||
@@ -348,8 +348,8 @@ class CPPObject(ObjectDescription[ASTDeclaration]):
|
||||
parent_symbol: Symbol = self.env.current_document.cpp_parent_symbol
|
||||
|
||||
max_len = (
|
||||
self.env.config.cpp_maximum_signature_line_length
|
||||
or self.env.config.maximum_signature_line_length
|
||||
self.config.cpp_maximum_signature_line_length
|
||||
or self.config.maximum_signature_line_length
|
||||
or 0
|
||||
)
|
||||
signode['multi_line_parameter_list'] = (
|
||||
@@ -357,7 +357,7 @@ class CPPObject(ObjectDescription[ASTDeclaration]):
|
||||
and (len(sig) > max_len > 0)
|
||||
)
|
||||
|
||||
parser = DefinitionParser(sig, location=signode, config=self.env.config)
|
||||
parser = DefinitionParser(sig, location=signode, config=self.config)
|
||||
try:
|
||||
ast = self.parse_definition(parser)
|
||||
parser.assert_end()
|
||||
@@ -440,7 +440,7 @@ class CPPObject(ObjectDescription[ASTDeclaration]):
|
||||
if not sig_node.get('_toc_parts'):
|
||||
return ''
|
||||
|
||||
config = self.env.config
|
||||
config = self.config
|
||||
objtype = sig_node.parent.get('objtype')
|
||||
if config.add_function_parentheses and objtype in {'function', 'method'}:
|
||||
parens = '()'
|
||||
@@ -710,7 +710,7 @@ class AliasTransform(SphinxTransform):
|
||||
sig = node.sig
|
||||
parent_key = node.parentKey
|
||||
try:
|
||||
parser = DefinitionParser(sig, location=node, config=self.env.config)
|
||||
parser = DefinitionParser(sig, location=node, config=self.config)
|
||||
ast, is_shorthand = parser.parse_xref_object()
|
||||
parser.assert_end()
|
||||
except DefinitionError as e:
|
||||
|
||||
@@ -101,8 +101,8 @@ class JSObject(ObjectDescription[tuple[str, str]]):
|
||||
signode['fullname'] = fullname
|
||||
|
||||
max_len = (
|
||||
self.env.config.javascript_maximum_signature_line_length
|
||||
or self.env.config.maximum_signature_line_length
|
||||
self.config.javascript_maximum_signature_line_length
|
||||
or self.config.maximum_signature_line_length
|
||||
or 0
|
||||
)
|
||||
multi_line_parameter_list = (
|
||||
@@ -238,7 +238,7 @@ class JSObject(ObjectDescription[tuple[str, str]]):
|
||||
if not sig_node.get('_toc_parts'):
|
||||
return ''
|
||||
|
||||
config = self.env.config
|
||||
config = self.config
|
||||
objtype = sig_node.parent.get('objtype')
|
||||
if config.add_function_parentheses and objtype in {'function', 'method'}:
|
||||
parens = '()'
|
||||
|
||||
@@ -261,7 +261,7 @@ class PyMethod(PyObject):
|
||||
name, cls = name_cls
|
||||
try:
|
||||
clsname, methname = name.rsplit('.', 1)
|
||||
if modname and self.env.config.add_module_names:
|
||||
if modname and self.config.add_module_names:
|
||||
clsname = f'{modname}.{clsname}'
|
||||
except ValueError:
|
||||
if modname:
|
||||
@@ -357,7 +357,7 @@ class PyAttribute(PyObject):
|
||||
name, cls = name_cls
|
||||
try:
|
||||
clsname, attrname = name.rsplit('.', 1)
|
||||
if modname and self.env.config.add_module_names:
|
||||
if modname and self.config.add_module_names:
|
||||
clsname = f'{modname}.{clsname}'
|
||||
except ValueError:
|
||||
if modname:
|
||||
@@ -417,7 +417,7 @@ class PyProperty(PyObject):
|
||||
name, cls = name_cls
|
||||
try:
|
||||
clsname, attrname = name.rsplit('.', 1)
|
||||
if modname and self.env.config.add_module_names:
|
||||
if modname and self.config.add_module_names:
|
||||
clsname = f'{modname}.{clsname}'
|
||||
except ValueError:
|
||||
if modname:
|
||||
@@ -457,7 +457,7 @@ class PyTypeAlias(PyObject):
|
||||
name, cls = name_cls
|
||||
try:
|
||||
clsname, attrname = name.rsplit('.', 1)
|
||||
if modname and self.env.config.add_module_names:
|
||||
if modname and self.config.add_module_names:
|
||||
clsname = f'{modname}.{clsname}'
|
||||
except ValueError:
|
||||
if modname:
|
||||
|
||||
@@ -286,8 +286,8 @@ class PyObject(ObjectDescription[tuple[str, str]]):
|
||||
signode['fullname'] = fullname
|
||||
|
||||
max_len = (
|
||||
self.env.config.python_maximum_signature_line_length
|
||||
or self.env.config.maximum_signature_line_length
|
||||
self.config.python_maximum_signature_line_length
|
||||
or self.config.maximum_signature_line_length
|
||||
or 0
|
||||
)
|
||||
|
||||
@@ -321,7 +321,7 @@ class PyObject(ObjectDescription[tuple[str, str]]):
|
||||
|
||||
if prefix:
|
||||
signode += addnodes.desc_addname(prefix, prefix)
|
||||
elif modname and add_module and self.env.config.add_module_names:
|
||||
elif modname and add_module and self.config.add_module_names:
|
||||
nodetext = f'{modname}.'
|
||||
signode += addnodes.desc_addname(nodetext, nodetext)
|
||||
|
||||
@@ -474,7 +474,7 @@ class PyObject(ObjectDescription[tuple[str, str]]):
|
||||
if not sig_node.get('_toc_parts'):
|
||||
return ''
|
||||
|
||||
config = self.env.config
|
||||
config = self.config
|
||||
objtype = sig_node.parent.get('objtype')
|
||||
if config.add_function_parentheses and objtype in {'function', 'method'}:
|
||||
parens = '()'
|
||||
|
||||
@@ -84,12 +84,11 @@ class ReSTMarkup(ObjectDescription[str]):
|
||||
if not sig_node.get('_toc_parts'):
|
||||
return ''
|
||||
|
||||
config = self.env.config
|
||||
objtype = sig_node.parent.get('objtype')
|
||||
*parents, name = sig_node['_toc_parts']
|
||||
if objtype == 'directive:option':
|
||||
return f':{name}:'
|
||||
if config.toc_object_entries_show_parents in {'domain', 'all'}:
|
||||
if self.config.toc_object_entries_show_parents in {'domain', 'all'}:
|
||||
name = ':'.join(sig_node['_toc_parts'])
|
||||
if objtype == 'role':
|
||||
return f':{name}:'
|
||||
|
||||
@@ -258,13 +258,13 @@ class Cmdoption(ObjectDescription[str]):
|
||||
args = '[' + args
|
||||
|
||||
if count:
|
||||
if self.env.config.option_emphasise_placeholders:
|
||||
if self.config.option_emphasise_placeholders:
|
||||
signode += addnodes.desc_sig_punctuation(',', ',')
|
||||
signode += addnodes.desc_sig_space()
|
||||
else:
|
||||
signode += addnodes.desc_addname(', ', ', ')
|
||||
signode += addnodes.desc_name(optname, optname)
|
||||
if self.env.config.option_emphasise_placeholders:
|
||||
if self.config.option_emphasise_placeholders:
|
||||
add_end_bracket = False
|
||||
if args:
|
||||
if args[0] == '[' and args[-1] == ']':
|
||||
|
||||
@@ -695,6 +695,7 @@ class BuildEnvironment:
|
||||
toctreenode,
|
||||
prune=prune_toctrees,
|
||||
includehidden=includehidden,
|
||||
tags=builder.tags,
|
||||
)
|
||||
if result is None:
|
||||
toctreenode.parent.replace(toctreenode, [])
|
||||
@@ -735,6 +736,7 @@ class BuildEnvironment:
|
||||
titles_only=titles_only,
|
||||
collapse=collapse,
|
||||
includehidden=includehidden,
|
||||
tags=builder.tags,
|
||||
)
|
||||
|
||||
def resolve_references(
|
||||
|
||||
@@ -86,6 +86,7 @@ def global_toctree_for_doc(
|
||||
titles_only=titles_only,
|
||||
collapse=collapse,
|
||||
includehidden=includehidden,
|
||||
tags=builder.tags,
|
||||
)
|
||||
for toctree_node in env.master_doctree.findall(addnodes.toctree)
|
||||
)
|
||||
@@ -110,6 +111,7 @@ def _resolve_toctree(
|
||||
titles_only: bool = False,
|
||||
collapse: bool = False,
|
||||
includehidden: bool = False,
|
||||
tags: Tags,
|
||||
) -> Element | None:
|
||||
"""Resolve a *toctree* node into individual bullet lists with titles
|
||||
as items, returning None (if no containing titles are found) or
|
||||
@@ -159,7 +161,7 @@ def _resolve_toctree(
|
||||
titles_only,
|
||||
collapse,
|
||||
includehidden,
|
||||
builder.tags,
|
||||
tags,
|
||||
toctree_ancestors,
|
||||
included,
|
||||
excluded,
|
||||
@@ -558,13 +560,14 @@ class TocTree:
|
||||
titles_only=titles_only,
|
||||
collapse=collapse,
|
||||
includehidden=includehidden,
|
||||
tags=builder.tags,
|
||||
)
|
||||
|
||||
def get_toctree_ancestors(self, docname: str) -> list[str]:
|
||||
return [*_get_toctree_ancestors(self.env.toctree_includes, docname)]
|
||||
|
||||
def get_toc_for(self, docname: str, builder: Builder) -> Node:
|
||||
return document_toc(self.env, docname, self.env.app.builder.tags)
|
||||
return document_toc(self.env, docname, self.env.app.tags)
|
||||
|
||||
def get_toctree_for(
|
||||
self,
|
||||
|
||||
@@ -73,9 +73,9 @@ class ImageCollector(EnvironmentCollector):
|
||||
# Search language-specific figures at first
|
||||
i18n_imguri = get_image_filename_for_language(imguri, app.env)
|
||||
_, full_i18n_imgpath = app.env.relfn2path(i18n_imguri, docname)
|
||||
self.collect_candidates(app.env, full_i18n_imgpath, candidates, node)
|
||||
self.collect_candidates(app.srcdir, full_i18n_imgpath, candidates, node)
|
||||
|
||||
self.collect_candidates(app.env, full_imgpath, candidates, node)
|
||||
self.collect_candidates(app.srcdir, full_imgpath, candidates, node)
|
||||
else:
|
||||
# substitute imguri by figure_language_filename
|
||||
# (ex. foo.png -> foo.en.png)
|
||||
@@ -106,14 +106,14 @@ class ImageCollector(EnvironmentCollector):
|
||||
|
||||
def collect_candidates(
|
||||
self,
|
||||
env: BuildEnvironment,
|
||||
srcdir: Path,
|
||||
imgpath: str,
|
||||
candidates: dict[str, str],
|
||||
node: Node,
|
||||
) -> None:
|
||||
globbed: dict[str, list[str]] = {}
|
||||
for filename in glob(imgpath):
|
||||
new_imgpath = _relative_path(Path(filename), env.srcdir)
|
||||
new_imgpath = _relative_path(Path(filename), srcdir)
|
||||
try:
|
||||
mimetype = guess_mimetype(filename)
|
||||
if mimetype is None:
|
||||
|
||||
@@ -46,7 +46,8 @@ if TYPE_CHECKING:
|
||||
from typing import ClassVar, Literal, TypeAlias
|
||||
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.environment import BuildEnvironment
|
||||
from sphinx.environment import BuildEnvironment, _CurrentDocument
|
||||
from sphinx.events import EventManager
|
||||
from sphinx.ext.autodoc.directive import DocumenterBridge
|
||||
|
||||
_AutodocObjType = Literal[
|
||||
@@ -370,6 +371,8 @@ class Documenter:
|
||||
self.directive = directive
|
||||
self.config: Config = directive.env.config
|
||||
self.env: BuildEnvironment = directive.env
|
||||
self._current_document: _CurrentDocument = directive.env.current_document
|
||||
self._events: EventManager = directive.env.events
|
||||
self.options = directive.genopt
|
||||
self.name = name
|
||||
self.indent = indent
|
||||
@@ -554,7 +557,7 @@ class Documenter:
|
||||
)
|
||||
args = None
|
||||
|
||||
result = self.env.events.emit_firstresult(
|
||||
result = self._events.emit_firstresult(
|
||||
'autodoc-process-signature',
|
||||
self.objtype,
|
||||
self.fullname,
|
||||
@@ -613,9 +616,9 @@ class Documenter:
|
||||
def process_doc(self, docstrings: list[list[str]]) -> Iterator[str]:
|
||||
"""Let the user process the docstrings before adding them."""
|
||||
for docstringlines in docstrings:
|
||||
if self.env.app:
|
||||
if self._events is not None:
|
||||
# let extensions preprocess docstrings
|
||||
self.env.events.emit(
|
||||
self._events.emit(
|
||||
'autodoc-process-docstring',
|
||||
self.objtype,
|
||||
self.fullname,
|
||||
@@ -840,9 +843,9 @@ class Documenter:
|
||||
|
||||
# give the user a chance to decide whether this member
|
||||
# should be skipped
|
||||
if self.env.app:
|
||||
if self._events is not None:
|
||||
# let extensions preprocess docstrings
|
||||
skip_user = self.env.events.emit_firstresult(
|
||||
skip_user = self._events.emit_firstresult(
|
||||
'autodoc-skip-member',
|
||||
self.objtype,
|
||||
membername,
|
||||
@@ -878,9 +881,9 @@ class Documenter:
|
||||
*self.options.members*.
|
||||
"""
|
||||
# set current namespace for finding members
|
||||
self.env.current_document.autodoc_module = self.modname
|
||||
self._current_document.autodoc_module = self.modname
|
||||
if self.objpath:
|
||||
self.env.current_document.autodoc_class = self.objpath[0]
|
||||
self._current_document.autodoc_class = self.objpath[0]
|
||||
|
||||
want_all = (
|
||||
all_members or self.options.inherited_members or self.options.members is ALL
|
||||
@@ -918,8 +921,8 @@ class Documenter:
|
||||
)
|
||||
|
||||
# reset current objects
|
||||
self.env.current_document.autodoc_module = ''
|
||||
self.env.current_document.autodoc_class = ''
|
||||
self._current_document.autodoc_module = ''
|
||||
self._current_document.autodoc_class = ''
|
||||
|
||||
def sort_members(
|
||||
self, documenters: list[tuple[Documenter, bool]], order: str
|
||||
@@ -1261,7 +1264,7 @@ class ModuleLevelDocumenter(Documenter):
|
||||
|
||||
# if documenting a toplevel object without explicit module,
|
||||
# it can be contained in another auto directive ...
|
||||
modname = self.env.current_document.autodoc_module
|
||||
modname = self._current_document.autodoc_module
|
||||
# ... or in the scope of a module directive
|
||||
if not modname:
|
||||
modname = self.env.ref_context.get('py:module')
|
||||
@@ -1287,7 +1290,7 @@ class ClassLevelDocumenter(Documenter):
|
||||
# if documenting a class-level object without path,
|
||||
# there must be a current class, either from a parent
|
||||
# auto directive ...
|
||||
mod_cls = self.env.current_document.autodoc_class
|
||||
mod_cls = self._current_document.autodoc_class
|
||||
# ... or from a class directive
|
||||
if not mod_cls:
|
||||
mod_cls = self.env.ref_context.get('py:class', '')
|
||||
@@ -1298,7 +1301,7 @@ class ClassLevelDocumenter(Documenter):
|
||||
parents = [cls]
|
||||
# if the module name is still missing, get it like above
|
||||
if not modname:
|
||||
modname = self.env.current_document.autodoc_module
|
||||
modname = self._current_document.autodoc_module
|
||||
if not modname:
|
||||
modname = self.env.ref_context.get('py:module')
|
||||
# ... else, it stays None, which means invalid
|
||||
@@ -1432,7 +1435,7 @@ class FunctionDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # typ
|
||||
kwargs.setdefault('unqualified_typehints', True)
|
||||
|
||||
try:
|
||||
self.env.events.emit('autodoc-before-process-signature', self.object, False)
|
||||
self._events.emit('autodoc-before-process-signature', self.object, False)
|
||||
sig = inspect.signature(
|
||||
self.object, type_aliases=self.config.autodoc_type_aliases
|
||||
)
|
||||
@@ -1685,7 +1688,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
|
||||
call = None
|
||||
|
||||
if call is not None:
|
||||
self.env.events.emit('autodoc-before-process-signature', call, True)
|
||||
self._events.emit('autodoc-before-process-signature', call, True)
|
||||
try:
|
||||
sig = inspect.signature(
|
||||
call,
|
||||
@@ -1704,7 +1707,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
|
||||
new = None
|
||||
|
||||
if new is not None:
|
||||
self.env.events.emit('autodoc-before-process-signature', new, True)
|
||||
self._events.emit('autodoc-before-process-signature', new, True)
|
||||
try:
|
||||
sig = inspect.signature(
|
||||
new,
|
||||
@@ -1718,7 +1721,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
|
||||
# Finally, we should have at least __init__ implemented
|
||||
init = get_user_defined_function_or_method(self.object, '__init__')
|
||||
if init is not None:
|
||||
self.env.events.emit('autodoc-before-process-signature', init, True)
|
||||
self._events.emit('autodoc-before-process-signature', init, True)
|
||||
try:
|
||||
sig = inspect.signature(
|
||||
init,
|
||||
@@ -1733,7 +1736,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
|
||||
# handle it.
|
||||
# We don't know the exact method that inspect.signature will read
|
||||
# the signature from, so just pass the object itself to our hook.
|
||||
self.env.events.emit('autodoc-before-process-signature', self.object, False)
|
||||
self._events.emit('autodoc-before-process-signature', self.object, False)
|
||||
try:
|
||||
sig = inspect.signature(
|
||||
self.object,
|
||||
@@ -1886,7 +1889,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
|
||||
else:
|
||||
bases = []
|
||||
|
||||
self.env.events.emit(
|
||||
self._events.emit(
|
||||
'autodoc-process-bases', self.fullname, self.object, self.options, bases
|
||||
)
|
||||
|
||||
@@ -2387,7 +2390,7 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type:
|
||||
if inspect.isstaticmethod(
|
||||
self.object, cls=self.parent, name=self.object_name
|
||||
):
|
||||
self.env.events.emit(
|
||||
self._events.emit(
|
||||
'autodoc-before-process-signature', self.object, False
|
||||
)
|
||||
sig = inspect.signature(
|
||||
@@ -2396,7 +2399,7 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type:
|
||||
type_aliases=self.config.autodoc_type_aliases,
|
||||
)
|
||||
else:
|
||||
self.env.events.emit(
|
||||
self._events.emit(
|
||||
'autodoc-before-process-signature', self.object, True
|
||||
)
|
||||
sig = inspect.signature(
|
||||
@@ -3049,7 +3052,7 @@ class PropertyDocumenter(DocstringStripSignatureMixin, ClassLevelDocumenter): #
|
||||
return ''
|
||||
|
||||
# update the annotations of the property getter
|
||||
self.env.events.emit('autodoc-before-process-signature', func, False)
|
||||
self._events.emit('autodoc-before-process-signature', func, False)
|
||||
# correctly format the arguments for a property
|
||||
return super().format_args(**kwargs)
|
||||
|
||||
|
||||
@@ -870,7 +870,7 @@ def process_generate_options(app: Sphinx) -> None:
|
||||
genfiles = app.config.autosummary_generate
|
||||
|
||||
if genfiles is True:
|
||||
env = app.builder.env
|
||||
env = app.env
|
||||
genfiles = [
|
||||
str(env.doc2path(x, base=False))
|
||||
for x in env.found_docs
|
||||
|
||||
@@ -240,6 +240,7 @@ def fix_svg_relative_paths(
|
||||
self: HTML5Translator | LaTeXTranslator | TexinfoTranslator, filepath: str
|
||||
) -> None:
|
||||
"""Change relative links in generated svg files to be relative to imgpath."""
|
||||
env = self.builder.env
|
||||
tree = ET.parse(filepath) # NoQA: S314
|
||||
root = tree.getroot()
|
||||
ns = {'svg': 'http://www.w3.org/2000/svg', 'xlink': 'http://www.w3.org/1999/xlink'}
|
||||
@@ -255,11 +256,11 @@ def fix_svg_relative_paths(
|
||||
# not a relative link
|
||||
continue
|
||||
|
||||
docname = self.builder.env.path2doc(self.document['source'])
|
||||
docname = env.path2doc(self.document['source'])
|
||||
if docname is None:
|
||||
# This shouldn't happen!
|
||||
continue
|
||||
doc_dir = self.builder.app.outdir.joinpath(docname).resolve().parent
|
||||
doc_dir = self.builder.outdir.joinpath(docname).resolve().parent
|
||||
|
||||
old_path = doc_dir / rel_uri
|
||||
img_path = doc_dir / self.builder.imgpath
|
||||
|
||||
@@ -58,7 +58,7 @@ if TYPE_CHECKING:
|
||||
from docutils.nodes import Node
|
||||
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.environment import BuildEnvironment
|
||||
from sphinx.config import Config
|
||||
from sphinx.util.typing import ExtensionMetadata, OptionSpec
|
||||
from sphinx.writers.html5 import HTML5Translator
|
||||
from sphinx.writers.latex import LaTeXTranslator
|
||||
@@ -302,7 +302,7 @@ class InheritanceGraph:
|
||||
self,
|
||||
name: str,
|
||||
urls: dict[str, str] | None = None,
|
||||
env: BuildEnvironment | None = None,
|
||||
config: Config | None = None,
|
||||
graph_attrs: dict | None = None,
|
||||
node_attrs: dict | None = None,
|
||||
edge_attrs: dict | None = None,
|
||||
@@ -328,10 +328,10 @@ class InheritanceGraph:
|
||||
n_attrs.update(node_attrs)
|
||||
if edge_attrs is not None:
|
||||
e_attrs.update(edge_attrs)
|
||||
if env:
|
||||
g_attrs.update(env.config.inheritance_graph_attrs)
|
||||
n_attrs.update(env.config.inheritance_node_attrs)
|
||||
e_attrs.update(env.config.inheritance_edge_attrs)
|
||||
if config:
|
||||
g_attrs.update(config.inheritance_graph_attrs)
|
||||
n_attrs.update(config.inheritance_node_attrs)
|
||||
e_attrs.update(config.inheritance_edge_attrs)
|
||||
|
||||
res: list[str] = [
|
||||
f'digraph {name} {{\n',
|
||||
@@ -450,7 +450,7 @@ def html_visit_inheritance_diagram(
|
||||
name = 'inheritance%s' % graph_hash
|
||||
|
||||
# Create a mapping from fully-qualified class names to URLs.
|
||||
graphviz_output_format = self.builder.env.config.graphviz_output_format.upper()
|
||||
graphviz_output_format = self.config.graphviz_output_format.upper()
|
||||
current_filename = os.path.basename(
|
||||
self.builder.current_docname + self.builder.out_suffix
|
||||
)
|
||||
@@ -471,7 +471,7 @@ def html_visit_inheritance_diagram(
|
||||
else:
|
||||
urls[child['reftitle']] = '#' + child.get('refid')
|
||||
|
||||
dotcode = graph.generate_dot(name, urls, env=self.builder.env)
|
||||
dotcode = graph.generate_dot(name, urls, config=self.config)
|
||||
render_dot_html(
|
||||
self,
|
||||
node,
|
||||
@@ -496,7 +496,7 @@ def latex_visit_inheritance_diagram(
|
||||
name = 'inheritance%s' % graph_hash
|
||||
|
||||
dotcode = graph.generate_dot(
|
||||
name, env=self.builder.env, graph_attrs={'size': '"6.0,6.0"'}
|
||||
name, config=self.config, graph_attrs={'size': '"6.0,6.0"'}
|
||||
)
|
||||
render_dot_latex(self, node, dotcode, {}, 'inheritance')
|
||||
raise nodes.SkipNode
|
||||
@@ -515,7 +515,7 @@ def texinfo_visit_inheritance_diagram(
|
||||
name = 'inheritance%s' % graph_hash
|
||||
|
||||
dotcode = graph.generate_dot(
|
||||
name, env=self.builder.env, graph_attrs={'size': '"6.0,6.0"'}
|
||||
name, config=self.config, graph_attrs={'size': '"6.0,6.0"'}
|
||||
)
|
||||
render_dot_texinfo(self, node, dotcode, {}, 'inheritance')
|
||||
raise nodes.SkipNode
|
||||
|
||||
@@ -140,8 +140,9 @@ def load_mappings(app: Sphinx) -> None:
|
||||
|
||||
The intersphinx mappings are expected to be normalized.
|
||||
"""
|
||||
env = app.env
|
||||
now = int(time.time())
|
||||
inventories = InventoryAdapter(app.builder.env)
|
||||
inventories = InventoryAdapter(env)
|
||||
intersphinx_cache: dict[InventoryURI, InventoryCacheEntry] = inventories.cache
|
||||
intersphinx_mapping: IntersphinxMapping = app.config.intersphinx_mapping
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ class LinkcodeError(SphinxError):
|
||||
|
||||
|
||||
def doctree_read(app: Sphinx, doctree: Node) -> None:
|
||||
env = app.builder.env
|
||||
env = app.env
|
||||
|
||||
resolve_target = getattr(env.config, 'linkcode_resolve', None)
|
||||
if not callable(env.config.linkcode_resolve):
|
||||
|
||||
@@ -87,7 +87,7 @@ def is_supported_builder(builder: Builder) -> bool:
|
||||
|
||||
|
||||
def doctree_read(app: Sphinx, doctree: Node) -> None:
|
||||
env = app.builder.env
|
||||
env = app.env
|
||||
if not hasattr(env, '_viewcode_modules'):
|
||||
env._viewcode_modules = {} # type: ignore[attr-defined]
|
||||
|
||||
@@ -251,7 +251,7 @@ def should_generate_module_page(app: Sphinx, modname: str) -> bool:
|
||||
|
||||
|
||||
def collect_pages(app: Sphinx) -> Iterator[tuple[str, dict[str, Any], str]]:
|
||||
env = app.builder.env
|
||||
env = app.env
|
||||
if not hasattr(env, '_viewcode_modules'):
|
||||
return
|
||||
if not is_supported_builder(app.builder):
|
||||
|
||||
@@ -272,7 +272,8 @@ class IndexBuilder:
|
||||
def __init__(
|
||||
self, env: BuildEnvironment, lang: str, options: dict[str, str], scoring: str
|
||||
) -> None:
|
||||
self.env = env
|
||||
self._domains = env.domains
|
||||
self._env_version = env.version
|
||||
# docname -> title
|
||||
self._titles: dict[str, str | None] = env._search_index_titles
|
||||
# docname -> filename
|
||||
@@ -323,7 +324,10 @@ class IndexBuilder:
|
||||
format = self.formats[format]
|
||||
frozen = format.load(stream)
|
||||
# if an old index is present, we treat it as not existing.
|
||||
if not isinstance(frozen, dict) or frozen.get('envversion') != self.env.version:
|
||||
if (
|
||||
not isinstance(frozen, dict)
|
||||
or frozen.get('envversion') != self._env_version
|
||||
):
|
||||
msg = 'old format'
|
||||
raise ValueError(msg)
|
||||
index2fn = frozen['docnames']
|
||||
@@ -362,7 +366,7 @@ class IndexBuilder:
|
||||
rv: dict[str, list[tuple[int, int, int, str, str]]] = {}
|
||||
otypes = self._objtypes
|
||||
onames = self._objnames
|
||||
for domain in self.env.domains.sorted():
|
||||
for domain in self._domains.sorted():
|
||||
sorted_objects = sorted(domain.get_objects())
|
||||
for fullname, dispname, type, docname, anchor, prio in sorted_objects:
|
||||
if docname not in fn2index:
|
||||
@@ -452,7 +456,7 @@ class IndexBuilder:
|
||||
'objtypes': objtypes,
|
||||
'objnames': objnames,
|
||||
'titleterms': title_terms,
|
||||
'envversion': self.env.version,
|
||||
'envversion': self._env_version,
|
||||
'alltitles': alltitles,
|
||||
'indexentries': index_entries,
|
||||
}
|
||||
|
||||
@@ -16,20 +16,21 @@ if TYPE_CHECKING:
|
||||
|
||||
def parse(app: Sphinx, text: str, docname: str = 'index') -> nodes.document:
|
||||
"""Parse a string as reStructuredText with Sphinx application."""
|
||||
env = app.env
|
||||
try:
|
||||
app.env.current_document.docname = docname
|
||||
reader = SphinxStandaloneReader()
|
||||
reader.setup(app)
|
||||
parser = RSTParser()
|
||||
parser.set_application(app)
|
||||
with sphinx_domains(app.env):
|
||||
with sphinx_domains(env):
|
||||
return publish_doctree(
|
||||
text,
|
||||
str(app.srcdir / f'{docname}.rst'),
|
||||
reader=reader,
|
||||
parser=parser,
|
||||
settings_overrides={
|
||||
'env': app.env,
|
||||
'env': env,
|
||||
'gettext_compact': True,
|
||||
'input_encoding': 'utf-8',
|
||||
'output_encoding': 'unicode',
|
||||
@@ -37,4 +38,4 @@ def parse(app: Sphinx, text: str, docname: str = 'index') -> nodes.document:
|
||||
},
|
||||
)
|
||||
finally:
|
||||
app.env.current_document.docname = ''
|
||||
env.current_document.docname = ''
|
||||
@@ -277,7 +277,7 @@ class OnlyNodeTransform(SphinxPostTransform):
|
||||
# result in a "Losing ids" exception if there is a target node before
|
||||
# the only node, so we make sure docutils can transfer the id to
|
||||
# something, even if it's just a comment and will lose the id anyway...
|
||||
process_only_nodes(self.document, self.app.builder.tags)
|
||||
process_only_nodes(self.document, self.app.tags)
|
||||
|
||||
|
||||
class SigElementFallbackTransform(SphinxPostTransform):
|
||||
|
||||
@@ -83,7 +83,7 @@ class ImageDownloader(BaseImageConverter):
|
||||
timestamp: float = ceil(path.stat().st_mtime)
|
||||
headers['If-Modified-Since'] = epoch_to_rfc1123(timestamp)
|
||||
|
||||
config = self.app.config
|
||||
config = self.config
|
||||
r = requests.get(
|
||||
node['uri'],
|
||||
headers=headers,
|
||||
@@ -94,7 +94,7 @@ class ImageDownloader(BaseImageConverter):
|
||||
msg = __('Could not fetch remote image: %s [%d]')
|
||||
logger.warning(msg, node['uri'], r.status_code)
|
||||
else:
|
||||
self.app.env.original_image_uri[_StrPath(path)] = node['uri']
|
||||
self.env.original_image_uri[_StrPath(path)] = node['uri']
|
||||
|
||||
if r.status_code == 200:
|
||||
path.write_bytes(r.content)
|
||||
@@ -106,7 +106,7 @@ class ImageDownloader(BaseImageConverter):
|
||||
|
||||
def _process_image(self, node: nodes.image, path: Path) -> None:
|
||||
str_path = _StrPath(path)
|
||||
self.app.env.original_image_uri[str_path] = node['uri']
|
||||
self.env.original_image_uri[str_path] = node['uri']
|
||||
|
||||
mimetype = guess_mimetype(path, default='*')
|
||||
if mimetype != '*' and not path.suffix:
|
||||
@@ -114,14 +114,14 @@ class ImageDownloader(BaseImageConverter):
|
||||
ext = get_image_extension(mimetype) or ''
|
||||
with_ext = path.with_name(path.name + ext)
|
||||
os.replace(path, with_ext)
|
||||
self.app.env.original_image_uri.pop(str_path)
|
||||
self.app.env.original_image_uri[_StrPath(with_ext)] = node['uri']
|
||||
self.env.original_image_uri.pop(str_path)
|
||||
self.env.original_image_uri[_StrPath(with_ext)] = node['uri']
|
||||
path = with_ext
|
||||
path_str = str(path)
|
||||
node['candidates'].pop('?')
|
||||
node['candidates'][mimetype] = path_str
|
||||
node['uri'] = path_str
|
||||
self.app.env.images.add_file(self.env.docname, path_str)
|
||||
self.env.images.add_file(self.env.docname, path_str)
|
||||
|
||||
|
||||
class DataURIExtractor(BaseImageConverter):
|
||||
@@ -145,7 +145,7 @@ class DataURIExtractor(BaseImageConverter):
|
||||
ensuredir(os.path.join(self.imagedir, 'embeded'))
|
||||
digest = sha1(image.data, usedforsecurity=False).hexdigest()
|
||||
path = _StrPath(self.imagedir, 'embeded', digest + ext)
|
||||
self.app.env.original_image_uri[path] = node['uri']
|
||||
self.env.original_image_uri[path] = node['uri']
|
||||
|
||||
with open(path, 'wb') as f:
|
||||
f.write(image.data)
|
||||
@@ -154,7 +154,7 @@ class DataURIExtractor(BaseImageConverter):
|
||||
node['candidates'].pop('?')
|
||||
node['candidates'][image.mimetype] = path_str
|
||||
node['uri'] = path_str
|
||||
self.app.env.images.add_file(self.env.docname, path_str)
|
||||
self.env.images.add_file(self.env.docname, path_str)
|
||||
|
||||
|
||||
def get_filename_for(filename: str, mimetype: str) -> str:
|
||||
|
||||
@@ -410,7 +410,7 @@ class DocFieldTransformer:
|
||||
self.directive.domain or '',
|
||||
target,
|
||||
contnode=content[0],
|
||||
env=self.directive.state.document.settings.env,
|
||||
env=self.directive.env,
|
||||
)
|
||||
if _is_single_paragraph(field_body):
|
||||
paragraph = cast('nodes.paragraph', field_body[0])
|
||||
@@ -477,7 +477,7 @@ class DocFieldTransformer:
|
||||
else:
|
||||
fieldtype, items, location = entry
|
||||
fieldtypes = types.get(fieldtype.name, {})
|
||||
env = self.directive.state.document.settings.env
|
||||
env = self.directive.env
|
||||
inliner = self.directive.state.inliner
|
||||
domain = self.directive.domain or ''
|
||||
new_list += fieldtype.make_field(
|
||||
|
||||
@@ -726,6 +726,7 @@ class SphinxTranslator(nodes.NodeVisitor):
|
||||
self.builder = builder
|
||||
self.config = builder.config
|
||||
self.settings = document.settings
|
||||
self._domains = builder.env.domains
|
||||
|
||||
def dispatch_visit(self, node: Node) -> None:
|
||||
"""
|
||||
|
||||
@@ -419,9 +419,7 @@ class HTML5Translator(SphinxTranslator, BaseTranslator): # type: ignore[misc]
|
||||
self.body.append(prefix % '.'.join(map(str, numbers)) + ' ')
|
||||
self.body.append('</span>')
|
||||
|
||||
figtype = self.builder.env.domains.standard_domain.get_enumerable_node_type(
|
||||
node
|
||||
)
|
||||
figtype = self._domains.standard_domain.get_enumerable_node_type(node)
|
||||
if figtype:
|
||||
if len(node['ids']) == 0:
|
||||
msg = __('Any IDs not assigned for %s node') % node.tagname
|
||||
|
||||
@@ -560,7 +560,7 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
indices_config = frozenset(indices_config)
|
||||
else:
|
||||
check_names = False
|
||||
for domain in self.builder.env.domains.sorted():
|
||||
for domain in self._domains.sorted():
|
||||
for index_cls in domain.indices:
|
||||
index_name = f'{domain.name}-{index_cls.name}'
|
||||
if check_names and index_name not in indices_config:
|
||||
@@ -1816,7 +1816,7 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
while isinstance(next_node, nodes.target):
|
||||
next_node = next_node.next_node(ascend=True)
|
||||
|
||||
domain = self.builder.env.domains.standard_domain
|
||||
domain = self._domains.standard_domain
|
||||
if isinstance(next_node, HYPERLINK_SUPPORT_NODES):
|
||||
return
|
||||
if (
|
||||
|
||||
@@ -10,7 +10,6 @@ from typing import TYPE_CHECKING, Any, ClassVar, cast
|
||||
from docutils import nodes, writers
|
||||
|
||||
from sphinx import __display_version__, addnodes
|
||||
from sphinx.errors import ExtensionError
|
||||
from sphinx.locale import _, __, admonitionlabels
|
||||
from sphinx.util import logging
|
||||
from sphinx.util.docutils import SphinxTranslator
|
||||
@@ -493,7 +492,7 @@ class TexinfoTranslator(SphinxTranslator):
|
||||
indices_config = frozenset(indices_config)
|
||||
else:
|
||||
check_names = False
|
||||
for domain in self.builder.env.domains.sorted():
|
||||
for domain in self._domains.sorted():
|
||||
for index_cls in domain.indices:
|
||||
index_name = f'{domain.name}-{index_cls.name}'
|
||||
if check_names and index_name not in indices_config:
|
||||
@@ -507,7 +506,7 @@ class TexinfoTranslator(SphinxTranslator):
|
||||
generate(content, collapsed),
|
||||
))
|
||||
# only add the main Index if it's not empty
|
||||
domain = self.builder.env.domains.index_domain
|
||||
domain = self._domains.index_domain
|
||||
for docname in self.builder.docnames:
|
||||
if domain.entries[docname]:
|
||||
self.indices.append((_('Index'), '\n@printindex ge\n'))
|
||||
@@ -1420,11 +1419,11 @@ class TexinfoTranslator(SphinxTranslator):
|
||||
self.add_anchor(id, node)
|
||||
# use the full name of the objtype for the category
|
||||
try:
|
||||
domain = self.builder.env.get_domain(node.parent['domain'])
|
||||
domain = self._domains[node.parent['domain']]
|
||||
name = domain.get_type_name(
|
||||
domain.object_types[objtype], self.config.primary_domain == domain.name
|
||||
)
|
||||
except (KeyError, ExtensionError):
|
||||
except KeyError:
|
||||
name = objtype
|
||||
# by convention, the deffn category should be capitalized like a title
|
||||
category = self.escape_arg(smart_capwords(name))
|
||||
|
||||
@@ -16,10 +16,11 @@ class XMLWriter(BaseXMLWriter): # type: ignore[misc]
|
||||
def __init__(self, builder: Builder) -> None:
|
||||
super().__init__()
|
||||
self.builder = builder
|
||||
self._config = builder.config
|
||||
|
||||
def translate(self, *args: Any, **kwargs: Any) -> None:
|
||||
self.document.settings.newlines = self.document.settings.indents = (
|
||||
self.builder.env.config.xml_pretty
|
||||
self._config.xml_pretty
|
||||
)
|
||||
self.document.settings.xml_declaration = True
|
||||
self.document.settings.doctype_declaration = True
|
||||
|
||||
@@ -14,21 +14,24 @@ from sphinx.testing import restructuredtext
|
||||
from sphinx.util.docutils import sphinx_domains
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from sphinx.builders import Builder
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.environment import BuildEnvironment
|
||||
|
||||
|
||||
def _doctree_for_test(builder: Builder, docname: str) -> nodes.document:
|
||||
builder.env.prepare_settings(docname)
|
||||
publisher = create_publisher(builder.app, 'restructuredtext')
|
||||
with sphinx_domains(builder.env):
|
||||
publisher.set_source(source_path=str(builder.env.doc2path(docname)))
|
||||
def _doctree_for_test(
|
||||
app: Sphinx, env: BuildEnvironment, docname: str
|
||||
) -> nodes.document:
|
||||
env.prepare_settings(docname)
|
||||
publisher = create_publisher(app, 'restructuredtext')
|
||||
with sphinx_domains(env):
|
||||
publisher.set_source(source_path=str(env.doc2path(docname)))
|
||||
publisher.publish()
|
||||
return publisher.document
|
||||
|
||||
|
||||
@pytest.mark.sphinx('text', testroot='object-description-sections')
|
||||
def test_object_description_sections(app):
|
||||
doctree = _doctree_for_test(app.builder, 'index')
|
||||
doctree = _doctree_for_test(app, app.env, 'index')
|
||||
# <document>
|
||||
# <index>
|
||||
# <desc>
|
||||
|
||||
@@ -452,7 +452,7 @@ def test_domain_objects_document_scoping(app):
|
||||
@pytest.mark.test_params(shared_result='test_environment_toctree_basic')
|
||||
def test_document_toc(app):
|
||||
app.build()
|
||||
toctree = document_toc(app.env, 'index', app.builder.tags)
|
||||
toctree = document_toc(app.env, 'index', app.tags)
|
||||
|
||||
assert_node(
|
||||
toctree,
|
||||
@@ -502,8 +502,8 @@ def test_document_toc(app):
|
||||
@pytest.mark.test_params(shared_result='test_environment_toctree_basic')
|
||||
def test_document_toc_only(app):
|
||||
app.build()
|
||||
builder = StandaloneHTMLBuilder(app, app.env)
|
||||
toctree = document_toc(app.env, 'index', builder.tags)
|
||||
StandaloneHTMLBuilder(app, app.env) # adds format/builder tags
|
||||
toctree = document_toc(app.env, 'index', app.tags)
|
||||
|
||||
assert_node(
|
||||
toctree,
|
||||
@@ -561,7 +561,7 @@ def test_document_toc_only(app):
|
||||
@pytest.mark.test_params(shared_result='test_environment_toctree_basic')
|
||||
def test_document_toc_tocdepth(app):
|
||||
app.build()
|
||||
toctree = document_toc(app.env, 'tocdepth', app.builder.tags)
|
||||
toctree = document_toc(app.env, 'tocdepth', app.tags)
|
||||
|
||||
assert_node(
|
||||
toctree,
|
||||
|
||||
@@ -10,17 +10,18 @@ import functools
|
||||
import itertools
|
||||
import operator
|
||||
import sys
|
||||
from types import SimpleNamespace
|
||||
from typing import TYPE_CHECKING
|
||||
from unittest.mock import Mock
|
||||
from warnings import catch_warnings
|
||||
|
||||
import pytest
|
||||
from docutils.statemachine import ViewList
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx.ext.autodoc import ALL, ModuleLevelDocumenter, Options
|
||||
|
||||
# NEVER import these objects from sphinx.ext.autodoc directly
|
||||
from sphinx.ext.autodoc.directive import DocumenterBridge
|
||||
|
||||
from tests.test_extensions.autodoc_util import do_autodoc
|
||||
|
||||
try:
|
||||
@@ -34,8 +35,10 @@ except ImportError:
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any
|
||||
|
||||
from sphinx.environment import BuildEnvironment
|
||||
|
||||
def make_directive_bridge(env):
|
||||
|
||||
def make_directive_bridge(env: BuildEnvironment) -> DocumenterBridge:
|
||||
options = Options(
|
||||
inherited_members=False,
|
||||
undoc_members=False,
|
||||
@@ -54,11 +57,11 @@ def make_directive_bridge(env):
|
||||
ignore_module_all=False,
|
||||
)
|
||||
|
||||
directive = SimpleNamespace(
|
||||
directive = DocumenterBridge(
|
||||
env=env,
|
||||
genopt=options,
|
||||
result=ViewList(),
|
||||
record_dependencies=set(),
|
||||
reporter=None,
|
||||
options=options,
|
||||
lineno=0,
|
||||
state=Mock(),
|
||||
)
|
||||
directive.state.document.settings.tab_width = 8
|
||||
|
||||
@@ -26,6 +26,7 @@ from sphinx.writers.latex import LaTeXTranslator, LaTeXWriter
|
||||
|
||||
@pytest.fixture
|
||||
def settings(app):
|
||||
env = app.env
|
||||
texescape.init() # otherwise done by the latex builder
|
||||
with warnings.catch_warnings():
|
||||
warnings.filterwarnings('ignore', category=DeprecationWarning)
|
||||
@@ -37,10 +38,10 @@ def settings(app):
|
||||
)
|
||||
settings = optparser.get_default_values()
|
||||
settings.smart_quotes = True
|
||||
settings.env = app.builder.env
|
||||
settings.env = env
|
||||
settings.env.current_document.docname = 'dummy'
|
||||
settings.contentsname = 'dummy'
|
||||
domain_context = sphinx_domains(settings.env)
|
||||
domain_context = sphinx_domains(env)
|
||||
domain_context.enable()
|
||||
yield settings
|
||||
domain_context.disable()
|
||||
|
||||
@@ -29,7 +29,7 @@ def test_RSTParser_prolog_epilog(RSTStateMachine, app):
|
||||
]
|
||||
|
||||
# with rst_prolog
|
||||
app.env.config.rst_prolog = 'this is rst_prolog\nhello reST!'
|
||||
app.config.rst_prolog = 'this is rst_prolog\nhello reST!'
|
||||
parser.parse(text, document)
|
||||
(content, _), _ = RSTStateMachine().run.call_args
|
||||
assert list(content.xitems()) == [
|
||||
@@ -41,8 +41,8 @@ def test_RSTParser_prolog_epilog(RSTStateMachine, app):
|
||||
]
|
||||
|
||||
# with rst_epilog
|
||||
app.env.config.rst_prolog = None
|
||||
app.env.config.rst_epilog = 'this is rst_epilog\ngood-bye reST!'
|
||||
app.config.rst_prolog = None
|
||||
app.config.rst_epilog = 'this is rst_epilog\ngood-bye reST!'
|
||||
parser.parse(text, document)
|
||||
(content, _), _ = RSTStateMachine().run.call_args
|
||||
assert list(content.xitems()) == [
|
||||
@@ -54,8 +54,8 @@ def test_RSTParser_prolog_epilog(RSTStateMachine, app):
|
||||
]
|
||||
|
||||
# expandtabs / convert whitespaces
|
||||
app.env.config.rst_prolog = None
|
||||
app.env.config.rst_epilog = None
|
||||
app.config.rst_prolog = None
|
||||
app.config.rst_epilog = None
|
||||
text = '\thello Sphinx world\n\v\fSphinx is a document generator'
|
||||
parser.parse(text, document)
|
||||
(content, _), _ = RSTStateMachine().run.call_args
|
||||
|
||||
@@ -119,7 +119,7 @@ def test_get_filename_for_language(app):
|
||||
app.env.current_document.docname = 'index'
|
||||
|
||||
# language is en
|
||||
app.env.config.language = 'en'
|
||||
app.config.language = 'en'
|
||||
assert get_filename('foo.png', app.env) == 'foo.en.png'
|
||||
assert get_filename('foo.bar.png', app.env) == 'foo.bar.en.png'
|
||||
assert get_filename('dir/foo.png', app.env) == 'dir/foo.en.png'
|
||||
@@ -127,8 +127,8 @@ def test_get_filename_for_language(app):
|
||||
assert get_filename('foo', app.env) == 'foo.en'
|
||||
|
||||
# modify figure_language_filename and language is 'en'
|
||||
app.env.config.language = 'en'
|
||||
app.env.config.figure_language_filename = 'images/{language}/{root}{ext}'
|
||||
app.config.language = 'en'
|
||||
app.config.figure_language_filename = 'images/{language}/{root}{ext}'
|
||||
assert get_filename('foo.png', app.env) == 'images/en/foo.png'
|
||||
assert get_filename('foo.bar.png', app.env) == 'images/en/foo.bar.png'
|
||||
assert get_filename('subdir/foo.png', app.env) == 'images/en/subdir/foo.png'
|
||||
@@ -136,8 +136,8 @@ def test_get_filename_for_language(app):
|
||||
assert get_filename('foo', app.env) == 'images/en/foo'
|
||||
|
||||
# new path and basename tokens
|
||||
app.env.config.language = 'en'
|
||||
app.env.config.figure_language_filename = '{path}{language}/{basename}{ext}'
|
||||
app.config.language = 'en'
|
||||
app.config.figure_language_filename = '{path}{language}/{basename}{ext}'
|
||||
assert get_filename('foo.png', app.env) == 'en/foo.png'
|
||||
assert get_filename('foo.bar.png', app.env) == 'en/foo.bar.png'
|
||||
assert get_filename('subdir/foo.png', app.env) == 'subdir/en/foo.png'
|
||||
@@ -145,13 +145,13 @@ def test_get_filename_for_language(app):
|
||||
assert get_filename('foo', app.env) == 'en/foo'
|
||||
|
||||
# invalid figure_language_filename
|
||||
app.env.config.figure_language_filename = '{root}.{invalid}{ext}'
|
||||
app.config.figure_language_filename = '{root}.{invalid}{ext}'
|
||||
with pytest.raises(SphinxError):
|
||||
get_filename('foo.png', app.env)
|
||||
|
||||
# docpath (for a document in the top of source directory)
|
||||
app.env.config.language = 'en'
|
||||
app.env.config.figure_language_filename = '/{docpath}{language}/{basename}{ext}'
|
||||
app.config.language = 'en'
|
||||
app.config.figure_language_filename = '/{docpath}{language}/{basename}{ext}'
|
||||
assert get_filename('foo.png', app.env) == '/en/foo.png'
|
||||
|
||||
# docpath (for a document in the sub directory)
|
||||
|
||||
Reference in new issue
Block a user