summaryrefslogtreecommitdiffstats
path: root/sphinx/environment
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-05 16:20:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-05 16:20:58 +0000
commit5bb0bb4be543fd5eca41673696a62ed80d493591 (patch)
treead2c464f140e86c7f178a6276d7ea4a93e3e6c92 /sphinx/environment
parentAdding upstream version 7.2.6. (diff)
downloadsphinx-upstream.tar.xz
sphinx-upstream.zip
Adding upstream version 7.3.7.upstream/7.3.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sphinx/environment')
-rw-r--r--sphinx/environment/__init__.py40
-rw-r--r--sphinx/environment/adapters/indexentries.py4
-rw-r--r--sphinx/environment/adapters/toctree.py19
-rw-r--r--sphinx/environment/collectors/__init__.py9
-rw-r--r--sphinx/environment/collectors/asset.py7
-rw-r--r--sphinx/environment/collectors/dependencies.py5
-rw-r--r--sphinx/environment/collectors/metadata.py11
-rw-r--r--sphinx/environment/collectors/title.py5
-rw-r--r--sphinx/environment/collectors/toctree.py9
9 files changed, 60 insertions, 49 deletions
diff --git a/sphinx/environment/__init__.py b/sphinx/environment/__init__.py
index 9b9e9dd..e145c92 100644
--- a/sphinx/environment/__init__.py
+++ b/sphinx/environment/__init__.py
@@ -9,7 +9,7 @@ import time
from collections import defaultdict
from copy import copy
from os import path
-from typing import TYPE_CHECKING, Any, Callable
+from typing import TYPE_CHECKING, Any, Callable, NoReturn
from sphinx import addnodes
from sphinx.environment.adapters import toctree as toctree_adapters
@@ -23,7 +23,7 @@ from sphinx.util.nodes import is_translatable
from sphinx.util.osutil import canon_path, os_path
if TYPE_CHECKING:
- from collections.abc import Generator, Iterator
+ from collections.abc import Iterator
from pathlib import Path
from docutils import nodes
@@ -58,7 +58,7 @@ default_settings: dict[str, Any] = {
# This is increased every time an environment attribute is added
# or changed to properly invalidate pickle files.
-ENV_VERSION = 60
+ENV_VERSION = 61
# config status
CONFIG_UNSET = -1
@@ -81,9 +81,7 @@ versioning_conditions: dict[str, bool | Callable] = {
if TYPE_CHECKING:
from collections.abc import MutableMapping
- from typing import Literal
-
- from typing_extensions import overload
+ from typing import Literal, overload
from sphinx.domains.c import CDomain
from sphinx.domains.changeset import ChangeSetDomain
@@ -126,10 +124,12 @@ if TYPE_CHECKING:
@overload
def __getitem__(self, key: str) -> Domain: ... # NoQA: E704
def __getitem__(self, key): raise NotImplementedError # NoQA: E704
- def __setitem__(self, key, value): raise NotImplementedError # NoQA: E704
- def __delitem__(self, key): raise NotImplementedError # NoQA: E704
- def __iter__(self): raise NotImplementedError # NoQA: E704
- def __len__(self): raise NotImplementedError # NoQA: E704
+ def __setitem__( # NoQA: E301,E704
+ self, key: str, value: Domain,
+ ) -> NoReturn: raise NotImplementedError
+ def __delitem__(self, key: str) -> NoReturn: raise NotImplementedError # NoQA: E704
+ def __iter__(self) -> NoReturn: raise NotImplementedError # NoQA: E704
+ def __len__(self) -> NoReturn: raise NotImplementedError # NoQA: E704
else:
_DomainsType = dict
@@ -146,7 +146,7 @@ class BuildEnvironment:
# --------- ENVIRONMENT INITIALIZATION -------------------------------------
- def __init__(self, app: Sphinx):
+ def __init__(self, app: Sphinx) -> None:
self.app: Sphinx = app
self.doctreedir: Path = app.doctreedir
self.srcdir: Path = app.srcdir
@@ -155,7 +155,7 @@ class BuildEnvironment:
self.config_status_extra: str = ''
self.events: EventManager = app.events
self.project: Project = app.project
- self.version: dict[str, str] = app.registry.get_envversion(app)
+ self.version: dict[str, int] = app.registry.get_envversion(app)
# the method of doctree versioning; see set_versioning_method
self.versioning_condition: bool | Callable | None = None
@@ -265,6 +265,9 @@ class BuildEnvironment:
"""Obtains serializable data for pickling."""
__dict__ = self.__dict__.copy()
__dict__.update(app=None, domains={}, events=None) # clear unpickable attributes
+ # ensure that upon restoring the state, the most recent pickled files
+ # on the disk are used instead of those from a possibly outdated state
+ __dict__.update(_pickled_doctree_cache={})
return __dict__
def __setstate__(self, state: dict) -> None:
@@ -299,7 +302,7 @@ class BuildEnvironment:
# initialize config
self._update_config(app.config)
- # initialie settings
+ # initialize settings
self._update_settings(app.config)
def _update_config(self, config: Config) -> None:
@@ -320,7 +323,7 @@ class BuildEnvironment:
else:
# check if a config value was changed that affects how
# doctrees are read
- for item in config.filter('env'):
+ for item in config.filter(frozenset({'env'})):
if self.config[item.name] != item.value:
self.config_status = CONFIG_CHANGED
self.config_status_extra = f' ({item.name!r})'
@@ -338,7 +341,7 @@ class BuildEnvironment:
self.settings.setdefault('smart_quotes', True)
def set_versioning_method(self, method: str | Callable, compare: bool) -> None:
- """This sets the doctree versioning method for this environment.
+ """Set the doctree versioning method for this environment.
Versioning methods are a builder property; only builders with the same
versioning method can share the same doctree directory. Therefore, we
@@ -424,7 +427,7 @@ class BuildEnvironment:
@property
def found_docs(self) -> set[str]:
- """contains all existing docnames."""
+ """Contains all existing docnames."""
return self.project.docnames
def find_files(self, config: Config, builder: Builder) -> None:
@@ -521,7 +524,7 @@ class BuildEnvironment:
return added, changed, removed
- def check_dependents(self, app: Sphinx, already: set[str]) -> Generator[str, None, None]:
+ def check_dependents(self, app: Sphinx, already: set[str]) -> Iterator[str]:
to_rewrite: list[str] = []
for docnames in self.events.emit('env-get-updated', self):
to_rewrite.extend(docnames)
@@ -743,7 +746,6 @@ def _last_modified_time(filename: str | os.PathLike[str]) -> int:
We prefer to err on the side of re-rendering a file,
so we round up to the nearest microsecond.
"""
-
# upside-down floor division to get the ceiling
return -(os.stat(filename).st_mtime_ns // -1_000)
@@ -751,7 +753,7 @@ def _last_modified_time(filename: str | os.PathLike[str]) -> int:
def _format_modified_time(timestamp: int) -> str:
"""Return an RFC 3339 formatted string representing the given timestamp."""
seconds, fraction = divmod(timestamp, 10**6)
- return time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(seconds)) + f'.{fraction//1_000}'
+ return time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(seconds)) + f'.{fraction // 1_000}'
def _traverse_toctree(
diff --git a/sphinx/environment/adapters/indexentries.py b/sphinx/environment/adapters/indexentries.py
index 6fdbea6..a12e131 100644
--- a/sphinx/environment/adapters/indexentries.py
+++ b/sphinx/environment/adapters/indexentries.py
@@ -129,7 +129,7 @@ def _add_entry(word: str, subword: str, main: str | None, *,
def _key_func_0(entry: tuple[str, str]) -> tuple[bool, str]:
- """sort the index entries for same keyword."""
+ """Sort the index entries for same keyword."""
main, uri = entry
return not main, uri # show main entries at first
@@ -156,7 +156,7 @@ def _key_func_1(entry: tuple[str, list]) -> tuple[tuple[int, str], str]:
def _key_func_2(entry: tuple[str, list]) -> str:
- """sort the sub-index entries"""
+ """Sort the sub-index entries"""
key = unicodedata.normalize('NFD', entry[0].lower())
if key.startswith('\N{RIGHT-TO-LEFT MARK}'):
key = key[1:]
diff --git a/sphinx/environment/adapters/toctree.py b/sphinx/environment/adapters/toctree.py
index e50d10b..cfe717f 100644
--- a/sphinx/environment/adapters/toctree.py
+++ b/sphinx/environment/adapters/toctree.py
@@ -47,7 +47,6 @@ def document_toc(env: BuildEnvironment, docname: str, tags: Tags) -> Node:
For a ToC tree that shows the document's place in the
ToC structure, use `get_toctree_for`.
"""
-
tocdepth = env.metadata[docname].get('tocdepth', 0)
try:
toc = _toctree_copy(env.tocs[docname], 2, tocdepth, False, tags)
@@ -74,10 +73,8 @@ def global_toctree_for_doc(
This gives the global ToC, with all ancestors and their siblings.
"""
-
- toctrees: list[Element] = []
- for toctree_node in env.master_doctree.findall(addnodes.toctree):
- if toctree := _resolve_toctree(
+ resolved = (
+ _resolve_toctree(
env,
docname,
builder,
@@ -87,8 +84,13 @@ def global_toctree_for_doc(
titles_only=titles_only,
collapse=collapse,
includehidden=includehidden,
- ):
- toctrees.append(toctree)
+ )
+ for toctree_node in env.master_doctree.findall(addnodes.toctree)
+ )
+ toctrees = [
+ toctree for toctree in resolved if toctree is not None
+ ]
+
if not toctrees:
return None
result = toctrees[0]
@@ -113,7 +115,6 @@ def _resolve_toctree(
If *collapse* is True, all branches not containing docname will
be collapsed.
"""
-
if toctree.get('hidden', False) and not includehidden:
return None
@@ -250,7 +251,7 @@ def _entries_from_toctree(
included,
excluded,
sub_toc_node,
- [refdoc] + parents,
+ [refdoc, *parents],
subtree=True,
),
start=sub_toc_node.parent.index(sub_toc_node) + 1,
diff --git a/sphinx/environment/collectors/__init__.py b/sphinx/environment/collectors/__init__.py
index c7e069a..c12dd50 100644
--- a/sphinx/environment/collectors/__init__.py
+++ b/sphinx/environment/collectors/__init__.py
@@ -41,19 +41,22 @@ class EnvironmentCollector:
def clear_doc(self, app: Sphinx, env: BuildEnvironment, docname: str) -> None:
"""Remove specified data of a document.
- This method is called on the removal of the document."""
+ This method is called on the removal of the document.
+ """
raise NotImplementedError
def merge_other(self, app: Sphinx, env: BuildEnvironment,
docnames: set[str], other: BuildEnvironment) -> None:
"""Merge in specified data regarding docnames from a different `BuildEnvironment`
- object which coming from a subprocess in parallel builds."""
+ object which coming from a subprocess in parallel builds.
+ """
raise NotImplementedError
def process_doc(self, app: Sphinx, doctree: nodes.document) -> None:
"""Process a document and gather specific data from it.
- This method is called after the document is read."""
+ This method is called after the document is read.
+ """
raise NotImplementedError
def get_updated_docs(self, app: Sphinx, env: BuildEnvironment) -> list[str]:
diff --git a/sphinx/environment/collectors/asset.py b/sphinx/environment/collectors/asset.py
index c2066f4..451d659 100644
--- a/sphinx/environment/collectors/asset.py
+++ b/sphinx/environment/collectors/asset.py
@@ -5,7 +5,7 @@ from __future__ import annotations
import os
from glob import glob
from os import path
-from typing import TYPE_CHECKING, Any
+from typing import TYPE_CHECKING
from docutils import nodes
from docutils.utils import relative_path
@@ -22,6 +22,7 @@ if TYPE_CHECKING:
from sphinx.application import Sphinx
from sphinx.environment import BuildEnvironment
+ from sphinx.util.typing import ExtensionMetadata
logger = logging.getLogger(__name__)
@@ -121,7 +122,7 @@ class DownloadFileCollector(EnvironmentCollector):
env.dlfiles.merge_other(docnames, other.dlfiles)
def process_doc(self, app: Sphinx, doctree: nodes.document) -> None:
- """Process downloadable file paths. """
+ """Process downloadable file paths."""
for node in doctree.findall(addnodes.download_reference):
targetname = node['reftarget']
if '://' in targetname:
@@ -136,7 +137,7 @@ class DownloadFileCollector(EnvironmentCollector):
node['filename'] = app.env.dlfiles.add_file(app.env.docname, rel_filename)
-def setup(app: Sphinx) -> dict[str, Any]:
+def setup(app: Sphinx) -> ExtensionMetadata:
app.add_env_collector(ImageCollector)
app.add_env_collector(DownloadFileCollector)
diff --git a/sphinx/environment/collectors/dependencies.py b/sphinx/environment/collectors/dependencies.py
index df1f0c1..33b54b8 100644
--- a/sphinx/environment/collectors/dependencies.py
+++ b/sphinx/environment/collectors/dependencies.py
@@ -4,7 +4,7 @@ from __future__ import annotations
import os
from os import path
-from typing import TYPE_CHECKING, Any
+from typing import TYPE_CHECKING
from docutils.utils import relative_path
@@ -16,6 +16,7 @@ if TYPE_CHECKING:
from sphinx.application import Sphinx
from sphinx.environment import BuildEnvironment
+ from sphinx.util.typing import ExtensionMetadata
class DependenciesCollector(EnvironmentCollector):
@@ -47,7 +48,7 @@ class DependenciesCollector(EnvironmentCollector):
app.env.dependencies[app.env.docname].add(relpath)
-def setup(app: Sphinx) -> dict[str, Any]:
+def setup(app: Sphinx) -> ExtensionMetadata:
app.add_env_collector(DependenciesCollector)
return {
diff --git a/sphinx/environment/collectors/metadata.py b/sphinx/environment/collectors/metadata.py
index 5f737a9..bef3511 100644
--- a/sphinx/environment/collectors/metadata.py
+++ b/sphinx/environment/collectors/metadata.py
@@ -2,7 +2,7 @@
from __future__ import annotations
-from typing import TYPE_CHECKING, Any, cast
+from typing import TYPE_CHECKING, cast
from docutils import nodes
@@ -11,6 +11,7 @@ from sphinx.environment.collectors import EnvironmentCollector
if TYPE_CHECKING:
from sphinx.application import Sphinx
from sphinx.environment import BuildEnvironment
+ from sphinx.util.typing import ExtensionMetadata
class MetadataCollector(EnvironmentCollector):
@@ -29,7 +30,7 @@ class MetadataCollector(EnvironmentCollector):
Keep processing minimal -- just return what docutils says.
"""
- index = doctree.first_child_not_matching_class(nodes.PreBibliographic)
+ index = doctree.first_child_not_matching_class(nodes.PreBibliographic) # type: ignore[arg-type]
if index is None:
return
elif isinstance(doctree[index], nodes.docinfo):
@@ -46,11 +47,11 @@ class MetadataCollector(EnvironmentCollector):
md[field_name.astext()] = field_body.astext()
elif isinstance(node, nodes.TextElement):
# other children must be TextElement
- # see: https://docutils.sourceforge.io/docs/ref/doctree.html#bibliographic-elements # noqa: E501
+ # see: https://docutils.sourceforge.io/docs/ref/doctree.html#bibliographic-elements # NoQA: E501
md[node.__class__.__name__] = node.astext()
for name, value in md.items():
- if name in ('tocdepth',):
+ if name == 'tocdepth':
try:
value = int(value)
except ValueError:
@@ -60,7 +61,7 @@ class MetadataCollector(EnvironmentCollector):
doctree.pop(index)
-def setup(app: Sphinx) -> dict[str, Any]:
+def setup(app: Sphinx) -> ExtensionMetadata:
app.add_env_collector(MetadataCollector)
return {
diff --git a/sphinx/environment/collectors/title.py b/sphinx/environment/collectors/title.py
index 014d77a..0760557 100644
--- a/sphinx/environment/collectors/title.py
+++ b/sphinx/environment/collectors/title.py
@@ -2,7 +2,7 @@
from __future__ import annotations
-from typing import TYPE_CHECKING, Any
+from typing import TYPE_CHECKING
from docutils import nodes
@@ -12,6 +12,7 @@ from sphinx.transforms import SphinxContentsFilter
if TYPE_CHECKING:
from sphinx.application import Sphinx
from sphinx.environment import BuildEnvironment
+ from sphinx.util.typing import ExtensionMetadata
class TitleCollector(EnvironmentCollector):
@@ -51,7 +52,7 @@ class TitleCollector(EnvironmentCollector):
app.env.longtitles[app.env.docname] = longtitlenode
-def setup(app: Sphinx) -> dict[str, Any]:
+def setup(app: Sphinx) -> ExtensionMetadata:
app.add_env_collector(TitleCollector)
return {
diff --git a/sphinx/environment/collectors/toctree.py b/sphinx/environment/collectors/toctree.py
index 772591e..6ea148c 100644
--- a/sphinx/environment/collectors/toctree.py
+++ b/sphinx/environment/collectors/toctree.py
@@ -2,7 +2,7 @@
from __future__ import annotations
-from typing import TYPE_CHECKING, Any, TypeVar, cast
+from typing import TYPE_CHECKING, TypeVar, cast
from docutils import nodes
@@ -20,6 +20,7 @@ if TYPE_CHECKING:
from sphinx.application import Sphinx
from sphinx.environment import BuildEnvironment
+ from sphinx.util.typing import ExtensionMetadata
N = TypeVar('N')
@@ -201,7 +202,7 @@ class TocTreeCollector(EnvironmentCollector):
numstack[-1] += 1
reference = cast(nodes.reference, subnode[0])
if depth > 0:
- number = list(numstack)
+ number = numstack.copy()
secnums[reference['anchorname']] = tuple(numstack)
else:
number = None
@@ -283,7 +284,7 @@ class TocTreeCollector(EnvironmentCollector):
secnum = secnum[:env.config.numfig_secnum_depth]
counter[secnum] = counter.get(secnum, 0) + 1
- return secnum + (counter[secnum],)
+ return (*secnum, counter[secnum])
def register_fignumber(docname: str, secnum: tuple[int, ...],
figtype: str, fignode: Element) -> None:
@@ -345,7 +346,7 @@ def _make_anchor_name(ids: list[str], num_entries: list[int]) -> str:
return anchorname
-def setup(app: Sphinx) -> dict[str, Any]:
+def setup(app: Sphinx) -> ExtensionMetadata:
app.add_env_collector(TocTreeCollector)
return {