mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
[lint] use `types-docutils
instead of
docutils-stubs
for
docutils
` type annotations (#12012)
Co-authored-by: daniel.eades <daniel.eades@seebyte.com> Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
This commit is contained in:
parent
42a0d73160
commit
22cee42094
@ -85,7 +85,7 @@ lint = [
|
||||
"ruff==0.3.4",
|
||||
"mypy==1.9.0",
|
||||
"sphinx-lint",
|
||||
"docutils-stubs",
|
||||
"types-docutils",
|
||||
"types-requests",
|
||||
"pytest>=6.0",
|
||||
]
|
||||
|
@ -16,8 +16,8 @@ if TYPE_CHECKING:
|
||||
|
||||
# deprecated name -> (object to return, canonical path or empty string)
|
||||
_DEPRECATED_OBJECTS = {
|
||||
'meta': (nodes.meta, 'docutils.nodes.meta'), # type: ignore[attr-defined]
|
||||
'docutils_meta': (nodes.meta, 'docutils.nodes.meta'), # type: ignore[attr-defined]
|
||||
'meta': (nodes.meta, 'docutils.nodes.meta'),
|
||||
'docutils_meta': (nodes.meta, 'docutils.nodes.meta'),
|
||||
}
|
||||
|
||||
|
||||
@ -45,7 +45,7 @@ class document(nodes.document):
|
||||
|
||||
def set_id(self, node: Element, msgnode: Element | None = None,
|
||||
suggested_prefix: str = '') -> str:
|
||||
return super().set_id(node, msgnode, suggested_prefix) # type: ignore[call-arg]
|
||||
return super().set_id(node, msgnode, suggested_prefix)
|
||||
|
||||
|
||||
class translatable(nodes.Node):
|
||||
@ -89,7 +89,7 @@ class toctree(nodes.General, nodes.Element, translatable):
|
||||
|
||||
def preserve_original_messages(self) -> None:
|
||||
# toctree entries
|
||||
rawentries = self.setdefault('rawentries', [])
|
||||
rawentries: list[str] = self.setdefault('rawentries', [])
|
||||
for title, _docname in self['entries']:
|
||||
if title:
|
||||
rawentries.append(title)
|
||||
|
@ -520,7 +520,7 @@ class Builder:
|
||||
doctree.settings = doctree.settings.copy()
|
||||
doctree.settings.warning_stream = None
|
||||
doctree.settings.env = None
|
||||
doctree.settings.record_dependencies = None # type: ignore[assignment]
|
||||
doctree.settings.record_dependencies = None
|
||||
|
||||
doctree_filename = path.join(self.doctreedir, docname + '.doctree')
|
||||
ensuredir(path.dirname(doctree_filename))
|
||||
|
@ -67,7 +67,7 @@ class Catalog:
|
||||
line = origin.line
|
||||
if line is None:
|
||||
line = -1
|
||||
self.metadata[msg].append((origin.source, line, origin.uid))
|
||||
self.metadata[msg].append((origin.source, line, origin.uid)) # type: ignore[arg-type]
|
||||
|
||||
def __iter__(self) -> Generator[Message, None, None]:
|
||||
for message in self.messages:
|
||||
|
@ -53,6 +53,7 @@ if TYPE_CHECKING:
|
||||
from collections.abc import Iterable, Iterator, Set
|
||||
|
||||
from docutils.nodes import Node
|
||||
from docutils.readers import Reader
|
||||
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.config import _ConfigRebuild
|
||||
@ -200,7 +201,7 @@ class StandaloneHTMLBuilder(Builder):
|
||||
self._js_files: list[_JavaScript] = []
|
||||
|
||||
# Cached Publisher for writing doctrees to HTML
|
||||
reader = docutils.readers.doctree.Reader(parser_name='restructuredtext')
|
||||
reader: Reader = docutils.readers.doctree.Reader(parser_name='restructuredtext')
|
||||
pub = Publisher(
|
||||
reader=reader,
|
||||
parser=reader.parser,
|
||||
@ -437,7 +438,7 @@ class StandaloneHTMLBuilder(Builder):
|
||||
doc.append(node)
|
||||
self._publisher.set_source(doc)
|
||||
self._publisher.publish()
|
||||
return self._publisher.writer.parts # type: ignore[union-attr]
|
||||
return self._publisher.writer.parts
|
||||
|
||||
def prepare_writing(self, docnames: set[str]) -> None:
|
||||
# create the search indexer
|
||||
@ -767,7 +768,7 @@ class StandaloneHTMLBuilder(Builder):
|
||||
|
||||
def copy_download_files(self) -> None:
|
||||
def to_relpath(f: str) -> str:
|
||||
return relative_path(self.srcdir, f) # type: ignore[arg-type]
|
||||
return relative_path(self.srcdir, f)
|
||||
|
||||
# copy downloadable files
|
||||
if self.env.dlfiles:
|
||||
|
@ -115,7 +115,7 @@ class ShowUrlsTransform(SphinxPostTransform):
|
||||
node = node.parent
|
||||
|
||||
try:
|
||||
source = node['source'] # type: ignore[index]
|
||||
source = node['source']
|
||||
except TypeError:
|
||||
raise ValueError(__('Failed to get a docname!')) from None
|
||||
raise ValueError(__('Failed to get a docname '
|
||||
@ -523,7 +523,7 @@ class BibliographyTransform(SphinxPostTransform):
|
||||
citations += node
|
||||
|
||||
if len(citations) > 0:
|
||||
self.document += citations
|
||||
self.document += citations # type: ignore[attr-defined]
|
||||
|
||||
|
||||
class CitationReferenceTransform(SphinxPostTransform):
|
||||
|
@ -3,7 +3,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from typing import TYPE_CHECKING, Generic, TypeVar, cast
|
||||
from typing import TYPE_CHECKING, ClassVar, Generic, TypeVar, cast
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.parsers.rst import directives, roles
|
||||
@ -55,7 +55,7 @@ class ObjectDescription(SphinxDirective, Generic[ObjDescT]):
|
||||
required_arguments = 1
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = True
|
||||
option_spec: OptionSpec = {
|
||||
option_spec: ClassVar[OptionSpec] = {
|
||||
'no-index': directives.flag,
|
||||
'no-index-entry': directives.flag,
|
||||
'no-contents-entry': directives.flag,
|
||||
@ -296,7 +296,7 @@ class ObjectDescription(SphinxDirective, Generic[ObjDescT]):
|
||||
# If ``:no-index:`` is set, or there are no ids on the node
|
||||
# or any of its children, then just return the index node,
|
||||
# as Docutils expects a target node to have at least one id.
|
||||
if node_ids := [node_id for el in node.findall(nodes.Element)
|
||||
if node_ids := [node_id for el in node.findall(nodes.Element) # type: ignore[var-annotated]
|
||||
for node_id in el.get('ids', ())]:
|
||||
target_node = nodes.target(ids=node_ids)
|
||||
self.set_source_info(target_node)
|
||||
@ -320,7 +320,7 @@ class DefaultRole(SphinxDirective):
|
||||
role_name = self.arguments[0]
|
||||
role, messages = roles.role(role_name, self.state_machine.language,
|
||||
self.lineno, self.state.reporter)
|
||||
if role: # type: ignore[truthy-function]
|
||||
if role:
|
||||
docutils.register_role('', role) # type: ignore[arg-type]
|
||||
self.env.temp_data['default_role'] = role_name
|
||||
else:
|
||||
@ -342,7 +342,7 @@ class DefaultDomain(SphinxDirective):
|
||||
required_arguments = 1
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = False
|
||||
option_spec: OptionSpec = {}
|
||||
option_spec: ClassVar[OptionSpec] = {}
|
||||
|
||||
def run(self) -> list[Node]:
|
||||
domain_name = self.arguments[0].lower()
|
||||
|
@ -3,7 +3,7 @@ from __future__ import annotations
|
||||
import sys
|
||||
import textwrap
|
||||
from difflib import unified_diff
|
||||
from typing import TYPE_CHECKING, Any
|
||||
from typing import TYPE_CHECKING, Any, ClassVar
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.parsers.rst import directives
|
||||
@ -35,7 +35,7 @@ class Highlight(SphinxDirective):
|
||||
required_arguments = 1
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = False
|
||||
option_spec: OptionSpec = {
|
||||
option_spec: ClassVar[OptionSpec] = {
|
||||
'force': directives.flag,
|
||||
'linenothreshold': directives.positive_int,
|
||||
}
|
||||
@ -102,7 +102,7 @@ class CodeBlock(SphinxDirective):
|
||||
required_arguments = 0
|
||||
optional_arguments = 1
|
||||
final_argument_whitespace = False
|
||||
option_spec: OptionSpec = {
|
||||
option_spec: ClassVar[OptionSpec] = {
|
||||
'force': directives.flag,
|
||||
'linenos': directives.flag,
|
||||
'dedent': optional_int,
|
||||
@ -393,7 +393,7 @@ class LiteralInclude(SphinxDirective):
|
||||
required_arguments = 1
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = True
|
||||
option_spec: OptionSpec = {
|
||||
option_spec: ClassVar[OptionSpec] = {
|
||||
'dedent': optional_int,
|
||||
'linenos': directives.flag,
|
||||
'lineno-start': int,
|
||||
|
@ -3,7 +3,7 @@ from __future__ import annotations
|
||||
import re
|
||||
from os.path import abspath, relpath
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING, Any, cast
|
||||
from typing import TYPE_CHECKING, Any, ClassVar, cast
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.parsers.rst import directives
|
||||
@ -22,6 +22,8 @@ from sphinx.util.matching import Matcher, patfilter
|
||||
from sphinx.util.nodes import explicit_title_re
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from collections.abc import Sequence
|
||||
|
||||
from docutils.nodes import Element, Node
|
||||
|
||||
from sphinx.application import Sphinx
|
||||
@ -179,7 +181,7 @@ class Author(SphinxDirective):
|
||||
required_arguments = 1
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = True
|
||||
option_spec: OptionSpec = {}
|
||||
option_spec: ClassVar[OptionSpec] = {}
|
||||
|
||||
def run(self) -> list[Node]:
|
||||
if not self.config.show_authors:
|
||||
@ -221,7 +223,7 @@ class TabularColumns(SphinxDirective):
|
||||
required_arguments = 1
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = True
|
||||
option_spec: OptionSpec = {}
|
||||
option_spec: ClassVar[OptionSpec] = {}
|
||||
|
||||
def run(self) -> list[Node]:
|
||||
node = addnodes.tabular_col_spec()
|
||||
@ -239,7 +241,7 @@ class Centered(SphinxDirective):
|
||||
required_arguments = 1
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = True
|
||||
option_spec: OptionSpec = {}
|
||||
option_spec: ClassVar[OptionSpec] = {}
|
||||
|
||||
def run(self) -> list[Node]:
|
||||
if not self.arguments:
|
||||
@ -262,7 +264,7 @@ class Acks(SphinxDirective):
|
||||
required_arguments = 0
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = False
|
||||
option_spec: OptionSpec = {}
|
||||
option_spec: ClassVar[OptionSpec] = {}
|
||||
|
||||
def run(self) -> list[Node]:
|
||||
node = addnodes.acks()
|
||||
@ -285,7 +287,7 @@ class HList(SphinxDirective):
|
||||
required_arguments = 0
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = False
|
||||
option_spec: OptionSpec = {
|
||||
option_spec: ClassVar[OptionSpec] = {
|
||||
'columns': int,
|
||||
}
|
||||
|
||||
@ -323,7 +325,7 @@ class Only(SphinxDirective):
|
||||
required_arguments = 1
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = True
|
||||
option_spec: OptionSpec = {}
|
||||
option_spec: ClassVar[OptionSpec] = {}
|
||||
|
||||
def run(self) -> list[Node]:
|
||||
node = addnodes.only()
|
||||
@ -379,7 +381,7 @@ class Include(BaseInclude, SphinxDirective):
|
||||
"correctly", i.e. relative to source directory.
|
||||
"""
|
||||
|
||||
def run(self) -> list[Node]:
|
||||
def run(self) -> Sequence[Node]:
|
||||
|
||||
# To properly emit "include-read" events from included RST text,
|
||||
# we must patch the ``StateMachine.insert_input()`` method.
|
||||
@ -413,7 +415,7 @@ class Include(BaseInclude, SphinxDirective):
|
||||
# Only enable this patch if there are listeners for 'include-read'.
|
||||
if self.env.app.events.listeners.get('include-read'):
|
||||
# See https://github.com/python/mypy/issues/2427 for details on the mypy issue
|
||||
self.state_machine.insert_input = _insert_input # type: ignore[assignment]
|
||||
self.state_machine.insert_input = _insert_input
|
||||
|
||||
if self.arguments[0].startswith('<') and \
|
||||
self.arguments[0].endswith('>'):
|
||||
|
@ -2,13 +2,13 @@ from __future__ import annotations
|
||||
|
||||
import os
|
||||
from os import path
|
||||
from typing import TYPE_CHECKING, cast
|
||||
from typing import TYPE_CHECKING, ClassVar, cast
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.nodes import Node, make_id
|
||||
from docutils.parsers.rst import directives
|
||||
from docutils.parsers.rst.directives import images, tables
|
||||
from docutils.parsers.rst.directives.misc import Meta # type: ignore[attr-defined]
|
||||
from docutils.parsers.rst.directives.misc import Meta
|
||||
from docutils.parsers.rst.roles import set_classes
|
||||
|
||||
from sphinx.directives import optional_int
|
||||
@ -82,7 +82,7 @@ class Code(SphinxDirective):
|
||||
"""
|
||||
|
||||
optional_arguments = 1
|
||||
option_spec: OptionSpec = {
|
||||
option_spec: ClassVar[OptionSpec] = {
|
||||
'class': directives.class_option,
|
||||
'force': directives.flag,
|
||||
'name': directives.unchanged,
|
||||
@ -127,7 +127,7 @@ class MathDirective(SphinxDirective):
|
||||
required_arguments = 0
|
||||
optional_arguments = 1
|
||||
final_argument_whitespace = True
|
||||
option_spec: OptionSpec = {
|
||||
option_spec: ClassVar[OptionSpec] = {
|
||||
'label': directives.unchanged,
|
||||
'name': directives.unchanged,
|
||||
'class': directives.class_option,
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Any
|
||||
from typing import TYPE_CHECKING, Any, ClassVar
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.parsers.rst import directives
|
||||
@ -56,7 +56,7 @@ class CObject(ObjectDescription[ASTDeclaration]):
|
||||
Description of a C language object.
|
||||
"""
|
||||
|
||||
option_spec: OptionSpec = {
|
||||
option_spec: ClassVar[OptionSpec] = {
|
||||
'no-index-entry': directives.flag,
|
||||
'no-contents-entry': directives.flag,
|
||||
'no-typesetting': directives.flag,
|
||||
@ -297,7 +297,7 @@ class CNamespaceObject(SphinxDirective):
|
||||
required_arguments = 1
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = True
|
||||
option_spec: OptionSpec = {}
|
||||
option_spec: ClassVar[OptionSpec] = {}
|
||||
|
||||
def run(self) -> list[Node]:
|
||||
rootSymbol = self.env.domaindata['c']['root_symbol']
|
||||
@ -327,7 +327,7 @@ class CNamespacePushObject(SphinxDirective):
|
||||
required_arguments = 1
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = True
|
||||
option_spec: OptionSpec = {}
|
||||
option_spec: ClassVar[OptionSpec] = {}
|
||||
|
||||
def run(self) -> list[Node]:
|
||||
if self.arguments[0].strip() in ('NULL', '0', 'nullptr'):
|
||||
@ -358,7 +358,7 @@ class CNamespacePopObject(SphinxDirective):
|
||||
required_arguments = 0
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = True
|
||||
option_spec: OptionSpec = {}
|
||||
option_spec: ClassVar[OptionSpec] = {}
|
||||
|
||||
def run(self) -> list[Node]:
|
||||
stack = self.env.temp_data.get('c:namespace_stack', None)
|
||||
@ -517,7 +517,7 @@ class AliasTransform(SphinxTransform):
|
||||
|
||||
|
||||
class CAliasObject(ObjectDescription):
|
||||
option_spec: OptionSpec = {
|
||||
option_spec: ClassVar[OptionSpec] = {
|
||||
'maxdepth': directives.nonnegative_int,
|
||||
'noroot': directives.flag,
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Any, NamedTuple, cast
|
||||
from typing import TYPE_CHECKING, Any, ClassVar, NamedTuple, cast
|
||||
|
||||
from docutils import nodes
|
||||
|
||||
@ -52,7 +52,7 @@ class VersionChange(SphinxDirective):
|
||||
required_arguments = 1
|
||||
optional_arguments = 1
|
||||
final_argument_whitespace = True
|
||||
option_spec: OptionSpec = {}
|
||||
option_spec: ClassVar[OptionSpec] = {}
|
||||
|
||||
def run(self) -> list[Node]:
|
||||
node = addnodes.versionmodified()
|
||||
@ -123,7 +123,7 @@ class ChangeSetDomain(Domain):
|
||||
version = node['version']
|
||||
module = self.env.ref_context.get('py:module')
|
||||
objname = self.env.temp_data.get('object')
|
||||
changeset = ChangeSet(node['type'], self.env.docname, node.line,
|
||||
changeset = ChangeSet(node['type'], self.env.docname, node.line, # type: ignore[arg-type]
|
||||
module, objname, node.astext())
|
||||
self.changesets.setdefault(version, []).append(changeset)
|
||||
|
||||
|
@ -70,7 +70,7 @@ class CitationDomain(Domain):
|
||||
path = self.env.doc2path(self.citations[label][0])
|
||||
logger.warning(__('duplicate citation %s, other instance in %s'), label, path,
|
||||
location=node, type='ref', subtype='citation')
|
||||
self.citations[label] = (node['docname'], node['ids'][0], node.line)
|
||||
self.citations[label] = (node['docname'], node['ids'][0], node.line) # type: ignore[assignment]
|
||||
|
||||
def note_citation_reference(self, node: pending_xref) -> None:
|
||||
docnames = self.citation_refs.setdefault(node['reftarget'], set())
|
||||
|
@ -3,7 +3,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from typing import TYPE_CHECKING, Any
|
||||
from typing import TYPE_CHECKING, Any, ClassVar
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.parsers.rst import directives
|
||||
@ -65,7 +65,7 @@ class CPPObject(ObjectDescription[ASTDeclaration]):
|
||||
can_collapse=True),
|
||||
]
|
||||
|
||||
option_spec: OptionSpec = {
|
||||
option_spec: ClassVar[OptionSpec] = {
|
||||
'no-index-entry': directives.flag,
|
||||
'no-contents-entry': directives.flag,
|
||||
'no-typesetting': directives.flag,
|
||||
@ -394,7 +394,7 @@ class CPPNamespaceObject(SphinxDirective):
|
||||
required_arguments = 1
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = True
|
||||
option_spec: OptionSpec = {}
|
||||
option_spec: ClassVar[OptionSpec] = {}
|
||||
|
||||
def run(self) -> list[Node]:
|
||||
rootSymbol = self.env.domaindata['cpp']['root_symbol']
|
||||
@ -425,7 +425,7 @@ class CPPNamespacePushObject(SphinxDirective):
|
||||
required_arguments = 1
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = True
|
||||
option_spec: OptionSpec = {}
|
||||
option_spec: ClassVar[OptionSpec] = {}
|
||||
|
||||
def run(self) -> list[Node]:
|
||||
if self.arguments[0].strip() in ('NULL', '0', 'nullptr'):
|
||||
@ -457,7 +457,7 @@ class CPPNamespacePopObject(SphinxDirective):
|
||||
required_arguments = 0
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = True
|
||||
option_spec: OptionSpec = {}
|
||||
option_spec: ClassVar[OptionSpec] = {}
|
||||
|
||||
def run(self) -> list[Node]:
|
||||
stack = self.env.temp_data.get('cpp:namespace_stack', None)
|
||||
@ -634,7 +634,7 @@ class AliasTransform(SphinxTransform):
|
||||
|
||||
|
||||
class CPPAliasObject(ObjectDescription):
|
||||
option_spec: OptionSpec = {
|
||||
option_spec: ClassVar[OptionSpec] = {
|
||||
'maxdepth': directives.nonnegative_int,
|
||||
'noroot': directives.flag,
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Any
|
||||
from typing import TYPE_CHECKING, Any, ClassVar
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.parsers.rst import directives
|
||||
@ -68,7 +68,7 @@ class IndexDirective(SphinxDirective):
|
||||
required_arguments = 1
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = True
|
||||
option_spec: OptionSpec = {
|
||||
option_spec: ClassVar[OptionSpec] = {
|
||||
'name': directives.unchanged,
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import contextlib
|
||||
from typing import TYPE_CHECKING, Any, cast
|
||||
from typing import TYPE_CHECKING, Any, ClassVar, cast
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.parsers.rst import directives
|
||||
@ -46,7 +46,7 @@ class JSObject(ObjectDescription[tuple[str, str]]):
|
||||
#: based on directive nesting
|
||||
allow_nesting = False
|
||||
|
||||
option_spec: OptionSpec = {
|
||||
option_spec: ClassVar[OptionSpec] = {
|
||||
'no-index': directives.flag,
|
||||
'no-index-entry': directives.flag,
|
||||
'no-contents-entry': directives.flag,
|
||||
@ -298,7 +298,7 @@ class JSModule(SphinxDirective):
|
||||
required_arguments = 1
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = False
|
||||
option_spec: OptionSpec = {
|
||||
option_spec: ClassVar[OptionSpec] = {
|
||||
'no-index': directives.flag,
|
||||
'no-contents-entry': directives.flag,
|
||||
'no-typesetting': directives.flag,
|
||||
|
@ -5,7 +5,7 @@ from __future__ import annotations
|
||||
import builtins
|
||||
import inspect
|
||||
import typing
|
||||
from typing import TYPE_CHECKING, Any, NamedTuple, cast
|
||||
from typing import TYPE_CHECKING, Any, ClassVar, NamedTuple, cast
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.parsers.rst import directives
|
||||
@ -67,7 +67,7 @@ class ModuleEntry(NamedTuple):
|
||||
class PyFunction(PyObject):
|
||||
"""Description of a function."""
|
||||
|
||||
option_spec: OptionSpec = PyObject.option_spec.copy()
|
||||
option_spec: ClassVar[OptionSpec] = PyObject.option_spec.copy() # noqa: F821
|
||||
option_spec.update({
|
||||
'async': directives.flag,
|
||||
})
|
||||
@ -122,7 +122,7 @@ class PyDecoratorFunction(PyFunction):
|
||||
class PyVariable(PyObject):
|
||||
"""Description of a variable."""
|
||||
|
||||
option_spec: OptionSpec = PyObject.option_spec.copy()
|
||||
option_spec: ClassVar[OptionSpec] = PyObject.option_spec.copy()
|
||||
option_spec.update({
|
||||
'type': directives.unchanged,
|
||||
'value': directives.unchanged,
|
||||
@ -161,7 +161,7 @@ class PyClasslike(PyObject):
|
||||
Description of a class-like object (classes, interfaces, exceptions).
|
||||
"""
|
||||
|
||||
option_spec: OptionSpec = PyObject.option_spec.copy()
|
||||
option_spec: ClassVar[OptionSpec] = PyObject.option_spec.copy()
|
||||
option_spec.update({
|
||||
'final': directives.flag,
|
||||
})
|
||||
@ -189,7 +189,7 @@ class PyClasslike(PyObject):
|
||||
class PyMethod(PyObject):
|
||||
"""Description of a method."""
|
||||
|
||||
option_spec: OptionSpec = PyObject.option_spec.copy()
|
||||
option_spec: ClassVar[OptionSpec] = PyObject.option_spec.copy()
|
||||
option_spec.update({
|
||||
'abstractmethod': directives.flag,
|
||||
'async': directives.flag,
|
||||
@ -243,7 +243,7 @@ class PyMethod(PyObject):
|
||||
class PyClassMethod(PyMethod):
|
||||
"""Description of a classmethod."""
|
||||
|
||||
option_spec: OptionSpec = PyObject.option_spec.copy()
|
||||
option_spec: ClassVar[OptionSpec] = PyObject.option_spec.copy()
|
||||
|
||||
def run(self) -> list[Node]:
|
||||
self.name = 'py:method'
|
||||
@ -255,7 +255,7 @@ class PyClassMethod(PyMethod):
|
||||
class PyStaticMethod(PyMethod):
|
||||
"""Description of a staticmethod."""
|
||||
|
||||
option_spec: OptionSpec = PyObject.option_spec.copy()
|
||||
option_spec: ClassVar[OptionSpec] = PyObject.option_spec.copy()
|
||||
|
||||
def run(self) -> list[Node]:
|
||||
self.name = 'py:method'
|
||||
@ -283,7 +283,7 @@ class PyDecoratorMethod(PyMethod):
|
||||
class PyAttribute(PyObject):
|
||||
"""Description of an attribute."""
|
||||
|
||||
option_spec: OptionSpec = PyObject.option_spec.copy()
|
||||
option_spec: ClassVar[OptionSpec] = PyObject.option_spec.copy()
|
||||
option_spec.update({
|
||||
'type': directives.unchanged,
|
||||
'value': directives.unchanged,
|
||||
@ -385,7 +385,7 @@ class PyModule(SphinxDirective):
|
||||
required_arguments = 1
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = False
|
||||
option_spec: OptionSpec = {
|
||||
option_spec: ClassVar[OptionSpec] = {
|
||||
'platform': lambda x: x,
|
||||
'synopsis': lambda x: x,
|
||||
'no-index': directives.flag,
|
||||
@ -444,7 +444,7 @@ class PyCurrentModule(SphinxDirective):
|
||||
required_arguments = 1
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = False
|
||||
option_spec: OptionSpec = {}
|
||||
option_spec: ClassVar[OptionSpec] = {}
|
||||
|
||||
def run(self) -> list[Node]:
|
||||
modname = self.arguments[0].strip()
|
||||
|
@ -2,7 +2,7 @@ from __future__ import annotations
|
||||
|
||||
import contextlib
|
||||
import re
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING, ClassVar
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.parsers.rst import directives
|
||||
@ -76,13 +76,13 @@ class PyXrefMixin:
|
||||
result['reftarget'] = reftarget
|
||||
|
||||
result.clear()
|
||||
result += innernode(reftitle, reftitle)
|
||||
result += innernode(reftitle, reftitle) # type: ignore[call-arg]
|
||||
elif env.config.python_use_unqualified_type_names:
|
||||
children = result.children
|
||||
result.clear()
|
||||
|
||||
shortname = target.split('.')[-1]
|
||||
textnode = innernode('', shortname)
|
||||
textnode = innernode('', shortname) # type: ignore[call-arg]
|
||||
contnodes = [pending_xref_condition('', '', textnode, condition='resolved'),
|
||||
pending_xref_condition('', '', *children, condition='*')]
|
||||
result.extend(contnodes)
|
||||
@ -113,7 +113,7 @@ class PyXrefMixin:
|
||||
contnode = nodes.Text(sub_target)
|
||||
|
||||
if in_literal or delims_re.match(sub_target):
|
||||
results.append(contnode or innernode(sub_target, sub_target))
|
||||
results.append(contnode or innernode(sub_target, sub_target)) # type: ignore[call-arg]
|
||||
else:
|
||||
results.append(self.make_xref(rolename, domain, sub_target,
|
||||
innernode, contnode, env, inliner, location))
|
||||
@ -144,7 +144,7 @@ class PyObject(ObjectDescription[tuple[str, str]]):
|
||||
:vartype allow_nesting: bool
|
||||
"""
|
||||
|
||||
option_spec: OptionSpec = {
|
||||
option_spec: ClassVar[OptionSpec] = {
|
||||
'no-index': directives.flag,
|
||||
'no-index-entry': directives.flag,
|
||||
'no-contents-entry': directives.flag,
|
||||
|
@ -3,7 +3,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from typing import TYPE_CHECKING, Any, cast
|
||||
from typing import TYPE_CHECKING, Any, ClassVar, cast
|
||||
|
||||
from docutils.parsers.rst import directives
|
||||
|
||||
@ -36,7 +36,7 @@ class ReSTMarkup(ObjectDescription[str]):
|
||||
Description of generic reST markup.
|
||||
"""
|
||||
|
||||
option_spec: OptionSpec = {
|
||||
option_spec: ClassVar[OptionSpec] = {
|
||||
'no-index': directives.flag,
|
||||
'no-index-entry': directives.flag,
|
||||
'no-contents-entry': directives.flag,
|
||||
@ -142,7 +142,7 @@ class ReSTDirectiveOption(ReSTMarkup):
|
||||
Description of an option for reST directive.
|
||||
"""
|
||||
|
||||
option_spec: OptionSpec = ReSTMarkup.option_spec.copy()
|
||||
option_spec: ClassVar[OptionSpec] = ReSTMarkup.option_spec.copy()
|
||||
option_spec.update({
|
||||
'type': directives.unchanged,
|
||||
})
|
||||
|
@ -4,7 +4,7 @@ from __future__ import annotations
|
||||
|
||||
import re
|
||||
from copy import copy
|
||||
from typing import TYPE_CHECKING, Any, Callable, Final, cast
|
||||
from typing import TYPE_CHECKING, Any, Callable, ClassVar, Final, cast
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.nodes import Element, Node, system_message
|
||||
@ -112,7 +112,7 @@ class Target(SphinxDirective):
|
||||
required_arguments = 1
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = True
|
||||
option_spec: OptionSpec = {}
|
||||
option_spec: ClassVar[OptionSpec] = {}
|
||||
|
||||
def run(self) -> list[Node]:
|
||||
# normalize whitespace in fullname like XRefRole does
|
||||
@ -206,7 +206,7 @@ class Cmdoption(ObjectDescription[str]):
|
||||
|
||||
def add_target_and_index(self, firstname: str, sig: str, signode: desc_signature) -> None:
|
||||
currprogram = self.env.ref_context.get('std:program')
|
||||
for optname in signode.get('allnames', []):
|
||||
for optname in signode.get('allnames', []): # type: ignore[var-annotated]
|
||||
prefixes = ['cmdoption']
|
||||
if currprogram:
|
||||
prefixes.append(currprogram)
|
||||
@ -228,7 +228,7 @@ class Cmdoption(ObjectDescription[str]):
|
||||
descr = _('%s command line option') % currprogram
|
||||
else:
|
||||
descr = _('command line option')
|
||||
for option in signode.get('allnames', []):
|
||||
for option in signode.get('allnames', []): # type: ignore[var-annotated]
|
||||
entry = f'{descr}; {option}'
|
||||
self.indexnode['entries'].append(('pair', entry, signode['ids'][0], '', None))
|
||||
|
||||
@ -242,7 +242,7 @@ class Program(SphinxDirective):
|
||||
required_arguments = 1
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = True
|
||||
option_spec: OptionSpec = {}
|
||||
option_spec: ClassVar[OptionSpec] = {}
|
||||
|
||||
def run(self) -> list[Node]:
|
||||
program = ws_re.sub('-', self.arguments[0].strip())
|
||||
@ -306,7 +306,7 @@ class Glossary(SphinxDirective):
|
||||
required_arguments = 0
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = False
|
||||
option_spec: OptionSpec = {
|
||||
option_spec: ClassVar[OptionSpec] = {
|
||||
'sorted': directives.flag,
|
||||
}
|
||||
|
||||
@ -385,7 +385,7 @@ class Glossary(SphinxDirective):
|
||||
parts = split_term_classifiers(line)
|
||||
# parse the term with inline markup
|
||||
# classifiers (parts[1:]) will not be shown on doctree
|
||||
textnodes, sysmsg = self.state.inline_text(parts[0], # type: ignore[arg-type]
|
||||
textnodes, sysmsg = self.state.inline_text(parts[0],
|
||||
lineno)
|
||||
|
||||
# use first classifier as a index key
|
||||
@ -453,7 +453,7 @@ class ProductionList(SphinxDirective):
|
||||
required_arguments = 1
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = True
|
||||
option_spec: OptionSpec = {}
|
||||
option_spec: ClassVar[OptionSpec] = {}
|
||||
|
||||
def run(self) -> list[Node]:
|
||||
domain = cast(StandardDomain, self.env.get_domain('std'))
|
||||
|
@ -30,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):
|
||||
|
@ -13,7 +13,7 @@ import re
|
||||
import sys
|
||||
import warnings
|
||||
from inspect import Parameter, Signature
|
||||
from typing import TYPE_CHECKING, Any, Callable, TypeVar
|
||||
from typing import TYPE_CHECKING, Any, Callable, ClassVar, TypeVar
|
||||
|
||||
from docutils.statemachine import StringList
|
||||
|
||||
@ -319,7 +319,7 @@ class Documenter:
|
||||
#: true if the generated content may contain titles
|
||||
titles_allowed = True
|
||||
|
||||
option_spec: OptionSpec = {
|
||||
option_spec: ClassVar[OptionSpec] = {
|
||||
'no-index': bool_option,
|
||||
'noindex': bool_option,
|
||||
}
|
||||
@ -980,7 +980,7 @@ class ModuleDocumenter(Documenter):
|
||||
content_indent = ''
|
||||
_extra_indent = ' '
|
||||
|
||||
option_spec: OptionSpec = {
|
||||
option_spec: ClassVar[OptionSpec] = {
|
||||
'members': members_option, 'undoc-members': bool_option,
|
||||
'no-index': bool_option, 'inherited-members': inherited_members_option,
|
||||
'show-inheritance': bool_option, 'synopsis': identity,
|
||||
@ -1466,7 +1466,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
|
||||
|
||||
objtype = 'class'
|
||||
member_order = 20
|
||||
option_spec: OptionSpec = {
|
||||
option_spec: ClassVar[OptionSpec] = {
|
||||
'members': members_option, 'undoc-members': bool_option,
|
||||
'no-index': bool_option, 'inherited-members': inherited_members_option,
|
||||
'show-inheritance': bool_option, 'member-order': member_order_option,
|
||||
@ -2042,7 +2042,7 @@ class DataDocumenter(GenericAliasMixin,
|
||||
objtype = 'data'
|
||||
member_order = 40
|
||||
priority = -10
|
||||
option_spec: OptionSpec = dict(ModuleLevelDocumenter.option_spec)
|
||||
option_spec: ClassVar[OptionSpec] = dict(ModuleLevelDocumenter.option_spec)
|
||||
option_spec["annotation"] = annotation_option
|
||||
option_spec["no-value"] = bool_option
|
||||
|
||||
@ -2589,7 +2589,7 @@ class AttributeDocumenter(GenericAliasMixin, SlotsMixin, # type: ignore[misc]
|
||||
|
||||
objtype = 'attribute'
|
||||
member_order = 60
|
||||
option_spec: OptionSpec = dict(ModuleLevelDocumenter.option_spec)
|
||||
option_spec: ClassVar[OptionSpec] = dict(ModuleLevelDocumenter.option_spec)
|
||||
option_spec["annotation"] = annotation_option
|
||||
option_spec["no-value"] = bool_option
|
||||
|
||||
|
@ -115,7 +115,7 @@ class AutodocDirective(SphinxDirective):
|
||||
reporter = self.state.document.reporter
|
||||
|
||||
try:
|
||||
source, lineno = reporter.get_source_and_line( # type: ignore[attr-defined]
|
||||
source, lineno = reporter.get_source_and_line(
|
||||
self.lineno)
|
||||
except AttributeError:
|
||||
source, lineno = (None, None)
|
||||
|
@ -58,7 +58,7 @@ import sys
|
||||
from inspect import Parameter
|
||||
from os import path
|
||||
from types import ModuleType
|
||||
from typing import TYPE_CHECKING, Any, cast
|
||||
from typing import TYPE_CHECKING, Any, ClassVar, cast
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.parsers.rst import directives
|
||||
@ -218,7 +218,7 @@ class Autosummary(SphinxDirective):
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = False
|
||||
has_content = True
|
||||
option_spec: OptionSpec = {
|
||||
option_spec: ClassVar[OptionSpec] = {
|
||||
'caption': directives.unchanged_required,
|
||||
'toctree': directives.unchanged,
|
||||
'nosignatures': directives.flag,
|
||||
|
@ -11,7 +11,7 @@ import sys
|
||||
import time
|
||||
from io import StringIO
|
||||
from os import path
|
||||
from typing import TYPE_CHECKING, Any, Callable
|
||||
from typing import TYPE_CHECKING, Any, Callable, ClassVar
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.parsers.rst import directives
|
||||
@ -143,19 +143,19 @@ class TestDirective(SphinxDirective):
|
||||
|
||||
|
||||
class TestsetupDirective(TestDirective):
|
||||
option_spec: OptionSpec = {
|
||||
option_spec: ClassVar[OptionSpec] = {
|
||||
'skipif': directives.unchanged_required,
|
||||
}
|
||||
|
||||
|
||||
class TestcleanupDirective(TestDirective):
|
||||
option_spec: OptionSpec = {
|
||||
option_spec: ClassVar[OptionSpec] = {
|
||||
'skipif': directives.unchanged_required,
|
||||
}
|
||||
|
||||
|
||||
class DoctestDirective(TestDirective):
|
||||
option_spec: OptionSpec = {
|
||||
option_spec: ClassVar[OptionSpec] = {
|
||||
'hide': directives.flag,
|
||||
'no-trim-doctest-flags': directives.flag,
|
||||
'options': directives.unchanged,
|
||||
@ -166,7 +166,7 @@ class DoctestDirective(TestDirective):
|
||||
|
||||
|
||||
class TestcodeDirective(TestDirective):
|
||||
option_spec: OptionSpec = {
|
||||
option_spec: ClassVar[OptionSpec] = {
|
||||
'hide': directives.flag,
|
||||
'no-trim-doctest-flags': directives.flag,
|
||||
'pyversion': directives.unchanged_required,
|
||||
@ -176,7 +176,7 @@ class TestcodeDirective(TestDirective):
|
||||
|
||||
|
||||
class TestoutputDirective(TestDirective):
|
||||
option_spec: OptionSpec = {
|
||||
option_spec: ClassVar[OptionSpec] = {
|
||||
'hide': directives.flag,
|
||||
'no-trim-doctest-flags': directives.flag,
|
||||
'options': directives.unchanged,
|
||||
@ -371,14 +371,13 @@ Doctest summary
|
||||
filename of the document it's included in.
|
||||
"""
|
||||
try:
|
||||
filename = relpath(node.source, self.env.srcdir)\
|
||||
.rsplit(':docstring of ', maxsplit=1)[0]
|
||||
filename = relpath(node.source, self.env.srcdir).rsplit(':docstring of ', maxsplit=1)[0] # type: ignore[arg-type] # noqa: E501
|
||||
except Exception:
|
||||
filename = self.env.doc2path(docname, False)
|
||||
return filename
|
||||
|
||||
@staticmethod
|
||||
def get_line_number(node: Node) -> int:
|
||||
def get_line_number(node: Node) -> int | None:
|
||||
"""Get the real line number or admit we don't know."""
|
||||
# TODO: Work out how to store or calculate real (file-relative)
|
||||
# line numbers for doctest blocks in docstrings.
|
||||
@ -387,7 +386,7 @@ Doctest summary
|
||||
# not the file. This is correct where it is set, in
|
||||
# `docutils.nodes.Node.setup_child`, but Sphinx should report
|
||||
# relative to the file, not the docstring.
|
||||
return None # type: ignore[return-value]
|
||||
return None
|
||||
if node.line is not None:
|
||||
# TODO: find the root cause of this off by one error.
|
||||
return node.line - 1
|
||||
@ -428,21 +427,21 @@ Doctest summary
|
||||
def condition(node: Node) -> bool:
|
||||
return isinstance(node, (nodes.literal_block, nodes.comment)) \
|
||||
and 'testnodetype' in node
|
||||
for node in doctree.findall(condition): # type: Element
|
||||
if self.skipped(node):
|
||||
for node in doctree.findall(condition):
|
||||
if self.skipped(node): # type: ignore[arg-type]
|
||||
continue
|
||||
|
||||
source = node['test'] if 'test' in node else node.astext()
|
||||
source = node['test'] if 'test' in node else node.astext() # type: ignore[index, operator]
|
||||
filename = self.get_filename_for_node(node, docname)
|
||||
line_number = self.get_line_number(node)
|
||||
if not source:
|
||||
logger.warning(__('no code/output in %s block at %s:%s'),
|
||||
node.get('testnodetype', 'doctest'),
|
||||
node.get('testnodetype', 'doctest'), # type: ignore[attr-defined]
|
||||
filename, line_number)
|
||||
code = TestCode(source, type=node.get('testnodetype', 'doctest'),
|
||||
filename=filename, lineno=line_number,
|
||||
options=node.get('options'))
|
||||
node_groups = node.get('groups', ['default'])
|
||||
code = TestCode(source, type=node.get('testnodetype', 'doctest'), # type: ignore[attr-defined]
|
||||
filename=filename, lineno=line_number, # type: ignore[arg-type]
|
||||
options=node.get('options')) # type: ignore[attr-defined]
|
||||
node_groups = node.get('groups', ['default']) # type: ignore[attr-defined]
|
||||
if '*' in node_groups:
|
||||
add_to_all_groups.append(code)
|
||||
continue
|
||||
|
@ -11,7 +11,7 @@ from hashlib import sha1
|
||||
from itertools import chain
|
||||
from os import path
|
||||
from subprocess import CalledProcessError
|
||||
from typing import TYPE_CHECKING, Any
|
||||
from typing import TYPE_CHECKING, Any, ClassVar
|
||||
from urllib.parse import urlsplit, urlunsplit
|
||||
|
||||
from docutils import nodes
|
||||
@ -117,7 +117,7 @@ class Graphviz(SphinxDirective):
|
||||
required_arguments = 0
|
||||
optional_arguments = 1
|
||||
final_argument_whitespace = False
|
||||
option_spec: OptionSpec = {
|
||||
option_spec: ClassVar[OptionSpec] = {
|
||||
'alt': directives.unchanged,
|
||||
'align': align_spec,
|
||||
'caption': directives.unchanged,
|
||||
@ -186,7 +186,7 @@ class GraphvizSimple(SphinxDirective):
|
||||
required_arguments = 1
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = False
|
||||
option_spec: OptionSpec = {
|
||||
option_spec: ClassVar[OptionSpec] = {
|
||||
'alt': directives.unchanged,
|
||||
'align': align_spec,
|
||||
'caption': directives.unchanged,
|
||||
|
@ -16,7 +16,7 @@ namespace of the project configuration (that is, all variables from
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING, ClassVar
|
||||
|
||||
from docutils import nodes
|
||||
|
||||
@ -41,7 +41,7 @@ class IfConfig(SphinxDirective):
|
||||
required_arguments = 1
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = True
|
||||
option_spec: OptionSpec = {}
|
||||
option_spec: ClassVar[OptionSpec] = {}
|
||||
|
||||
def run(self) -> list[Node]:
|
||||
node = ifconfig()
|
||||
|
@ -37,7 +37,7 @@ import re
|
||||
from collections.abc import Iterable, Sequence
|
||||
from importlib import import_module
|
||||
from os import path
|
||||
from typing import TYPE_CHECKING, Any, cast
|
||||
from typing import TYPE_CHECKING, Any, ClassVar, cast
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.parsers.rst import directives
|
||||
@ -348,7 +348,7 @@ class InheritanceDiagram(SphinxDirective):
|
||||
required_arguments = 1
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = True
|
||||
option_spec: OptionSpec = {
|
||||
option_spec: ClassVar[OptionSpec] = {
|
||||
'parts': int,
|
||||
'private-bases': directives.flag,
|
||||
'caption': directives.unchanged,
|
||||
@ -378,7 +378,7 @@ class InheritanceDiagram(SphinxDirective):
|
||||
aliases=self.config.inheritance_alias,
|
||||
top_classes=node['top-classes'])
|
||||
except InheritanceException as err:
|
||||
return [node.document.reporter.warning(err, line=self.lineno)]
|
||||
return [node.document.reporter.warning(err, line=self.lineno)] # type: ignore[union-attr]
|
||||
|
||||
# Create xref nodes for each target of the graph's image map and
|
||||
# add them to the doc tree so that Sphinx can resolve the
|
||||
@ -386,7 +386,7 @@ class InheritanceDiagram(SphinxDirective):
|
||||
# removed from the doctree after we're done with them.
|
||||
for name in graph.get_all_class_names():
|
||||
refnodes, x = class_role( # type: ignore[call-arg,misc]
|
||||
'class', ':class:`%s`' % name, name, 0, self.state) # type: ignore[arg-type]
|
||||
'class', ':class:`%s`' % name, name, 0, self.state)
|
||||
node.extend(refnodes)
|
||||
# Store the graph object so we can use it to generate the
|
||||
# dot file later
|
||||
|
@ -9,7 +9,7 @@ from __future__ import annotations
|
||||
|
||||
import functools
|
||||
import operator
|
||||
from typing import TYPE_CHECKING, Any, cast
|
||||
from typing import TYPE_CHECKING, Any, ClassVar, cast
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.parsers.rst import directives
|
||||
@ -53,7 +53,7 @@ class Todo(BaseAdmonition, SphinxDirective):
|
||||
required_arguments = 0
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = False
|
||||
option_spec: OptionSpec = {
|
||||
option_spec: ClassVar[OptionSpec] = {
|
||||
'class': directives.class_option,
|
||||
'name': directives.unchanged,
|
||||
}
|
||||
@ -112,7 +112,7 @@ class TodoList(SphinxDirective):
|
||||
required_arguments = 0
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = False
|
||||
option_spec: OptionSpec = {}
|
||||
option_spec: ClassVar[OptionSpec] = {}
|
||||
|
||||
def run(self) -> list[Node]:
|
||||
# Simply insert an empty todolist node which will be replaced later
|
||||
|
@ -98,9 +98,9 @@ class SphinxStandaloneReader(SphinxBaseReader):
|
||||
self.transforms = self.transforms + app.registry.get_transforms()
|
||||
super().setup(app)
|
||||
|
||||
def read(self, source: Input, parser: Parser, settings: Values) -> nodes.document:
|
||||
def read(self, source: Input, parser: Parser, settings: Values) -> nodes.document: # type: ignore[type-arg]
|
||||
self.source = source
|
||||
if not self.parser:
|
||||
if not self.parser: # type: ignore[has-type]
|
||||
self.parser = parser
|
||||
self.settings = settings
|
||||
self.input = self.read_source(settings.env)
|
||||
@ -179,7 +179,7 @@ def create_publisher(app: Sphinx, filetype: str) -> Publisher:
|
||||
# CommonMarkParser.
|
||||
from docutils.parsers.rst import Parser as RSTParser
|
||||
|
||||
parser.settings_spec = RSTParser.settings_spec
|
||||
parser.settings_spec = RSTParser.settings_spec # type: ignore[misc]
|
||||
|
||||
pub = Publisher(
|
||||
reader=reader,
|
||||
|
@ -462,15 +462,15 @@ def setup(app: Sphinx) -> ExtensionMetadata:
|
||||
|
||||
for rolename, nodeclass in generic_docroles.items():
|
||||
generic = roles.GenericRole(rolename, nodeclass)
|
||||
role = roles.CustomRole(rolename, generic, {'classes': [rolename]})
|
||||
roles.register_local_role(rolename, role)
|
||||
role = roles.CustomRole(rolename, generic, {'classes': [rolename]}) # type: ignore[arg-type]
|
||||
roles.register_local_role(rolename, role) # type: ignore[arg-type]
|
||||
|
||||
for rolename, func in specific_docroles.items():
|
||||
roles.register_local_role(rolename, func)
|
||||
roles.register_local_role(rolename, func) # type: ignore[arg-type]
|
||||
|
||||
# Since docutils registers it as a canonical role, override it as a
|
||||
# canonical role as well.
|
||||
roles.register_canonical_role('code', code_role)
|
||||
roles.register_canonical_role('code', code_role) # type: ignore[arg-type]
|
||||
|
||||
return {
|
||||
'version': 'builtin',
|
||||
|
@ -182,7 +182,7 @@ js_index = _JavaScriptIndex()
|
||||
|
||||
|
||||
def _is_meta_keywords(
|
||||
node: nodes.meta, # type: ignore[name-defined]
|
||||
node: nodes.meta,
|
||||
lang: str | None,
|
||||
) -> bool:
|
||||
if node.get('name') == 'keywords':
|
||||
@ -234,7 +234,7 @@ class WordCollector(nodes.NodeVisitor):
|
||||
ids = node.parent['ids']
|
||||
self.found_titles.append((title, ids[0] if ids else None))
|
||||
self.found_title_words.extend(self.lang.split(title))
|
||||
elif isinstance(node, Element) and _is_meta_keywords(node, self.lang.lang):
|
||||
elif isinstance(node, Element) and _is_meta_keywords(node, self.lang.lang): # type: ignore[arg-type]
|
||||
keywords = node['content']
|
||||
keywords = [keyword.strip() for keyword in keywords.split(',')]
|
||||
self.found_words.extend(keywords)
|
||||
@ -495,7 +495,7 @@ class IndexBuilder:
|
||||
nodetext = re.sub(r'<[^<]+?>', '', nodetext)
|
||||
word_store.words.extend(split(nodetext))
|
||||
return
|
||||
elif (isinstance(node, nodes.meta) # type: ignore[attr-defined]
|
||||
elif (isinstance(node, nodes.meta)
|
||||
and _is_meta_keywords(node, language)):
|
||||
keywords = [keyword.strip() for keyword in node['content'].split(',')]
|
||||
word_store.words.extend(keywords)
|
||||
|
@ -81,7 +81,7 @@ class SphinxTransformer(Transformer):
|
||||
if not hasattr(self.document.settings, 'env') and self.env:
|
||||
self.document.settings.env = self.env
|
||||
|
||||
super().apply_transforms()
|
||||
super().apply_transforms() # type: ignore[misc]
|
||||
else:
|
||||
# wrap the target node by document node during transforming
|
||||
try:
|
||||
|
@ -78,7 +78,7 @@ def publish_msgstr(app: Sphinx, source: str, source_path: str, source_line: int,
|
||||
settings=settings,
|
||||
)
|
||||
with contextlib.suppress(IndexError): # empty node
|
||||
return doc[0] # type: ignore[return-value]
|
||||
return doc[0]
|
||||
return doc
|
||||
finally:
|
||||
config.rst_prolog = rst_prolog # type: ignore[attr-defined]
|
||||
@ -138,7 +138,7 @@ class _NodeUpdater:
|
||||
if old_name != new_name:
|
||||
# if name would be changed, replace node names and
|
||||
# document nameids mapping with new name.
|
||||
names = section_node.setdefault('names', [])
|
||||
names: list[str] = section_node.setdefault('names', [])
|
||||
names.append(new_name)
|
||||
# Original section name (reference target name) should be kept to refer
|
||||
# from other nodes which is still not translated or uses explicit target
|
||||
@ -394,7 +394,7 @@ class Locale(SphinxTransform):
|
||||
msgstr = '::\n\n' + indent(msgstr, ' ' * 3)
|
||||
|
||||
patch = publish_msgstr(self.app, msgstr, source,
|
||||
node.line, self.config, settings)
|
||||
node.line, self.config, settings) # type: ignore[arg-type]
|
||||
# FIXME: no warnings about inconsistent references in this part
|
||||
# XXX doctest and other block markup
|
||||
if not isinstance(patch, nodes.paragraph):
|
||||
@ -408,10 +408,10 @@ class Locale(SphinxTransform):
|
||||
for _id in node['ids']:
|
||||
parts = split_term_classifiers(msgstr)
|
||||
patch = publish_msgstr(
|
||||
self.app, parts[0] or '', source, node.line, self.config, settings,
|
||||
self.app, parts[0] or '', source, node.line, self.config, settings, # type: ignore[arg-type]
|
||||
)
|
||||
updater.patch = make_glossary_term(
|
||||
self.env, patch, parts[1] or '', source, node.line, _id, self.document,
|
||||
self.env, patch, parts[1] or '', source, node.line, _id, self.document, # type: ignore[arg-type]
|
||||
)
|
||||
processed = True
|
||||
|
||||
@ -440,11 +440,11 @@ class Locale(SphinxTransform):
|
||||
|
||||
# update translatable nodes
|
||||
if isinstance(node, addnodes.translatable):
|
||||
node.apply_translated_message(msg, msgstr) # type: ignore[attr-defined]
|
||||
node.apply_translated_message(msg, msgstr)
|
||||
continue
|
||||
|
||||
# update meta nodes
|
||||
if isinstance(node, nodes.meta): # type: ignore[attr-defined]
|
||||
if isinstance(node, nodes.meta):
|
||||
node['content'] = msgstr
|
||||
node['translated'] = True
|
||||
continue
|
||||
@ -474,11 +474,11 @@ class Locale(SphinxTransform):
|
||||
msgstr = msgstr + '\n' + '=' * len(msgstr) * 2
|
||||
|
||||
patch = publish_msgstr(self.app, msgstr, source,
|
||||
node.line, self.config, settings)
|
||||
node.line, self.config, settings) # type: ignore[arg-type]
|
||||
# Structural Subelements phase2
|
||||
if isinstance(node, nodes.title):
|
||||
# get <title> node that placed as a first child
|
||||
patch = patch.next_node()
|
||||
patch = patch.next_node() # type: ignore[assignment]
|
||||
|
||||
# ignore unexpected markups in translation message
|
||||
unexpected: tuple[type[nodes.Element], ...] = (
|
||||
@ -588,10 +588,10 @@ class AddTranslationClasses(SphinxTransform):
|
||||
for node in NodeMatcher(nodes.Element, translated=Any).findall(self.document):
|
||||
if node['translated']:
|
||||
if add_translated:
|
||||
node.setdefault('classes', []).append('translated')
|
||||
node.setdefault('classes', []).append('translated') # type: ignore[arg-type]
|
||||
else:
|
||||
if add_untranslated:
|
||||
node.setdefault('classes', []).append('untranslated')
|
||||
node.setdefault('classes', []).append('untranslated') # type: ignore[arg-type]
|
||||
|
||||
|
||||
class RemoveTranslatableInline(SphinxTransform):
|
||||
|
@ -78,7 +78,7 @@ class Field:
|
||||
assert env is not None
|
||||
assert (inliner is None) == (location is None), (inliner, location)
|
||||
if not rolename:
|
||||
return contnode or innernode(target, target)
|
||||
return contnode or innernode(target, target) # type: ignore[call-arg]
|
||||
# The domain is passed from DocFieldTransformer. So it surely exists.
|
||||
# So we don't need to take care the env.get_domain() raises an exception.
|
||||
role = env.get_domain(domain).role(rolename)
|
||||
@ -89,7 +89,7 @@ class Field:
|
||||
logger.warning(__(msg), domain, rolename, location=location)
|
||||
refnode = addnodes.pending_xref('', refdomain=domain, refexplicit=False,
|
||||
reftype=rolename, reftarget=target)
|
||||
refnode += contnode or innernode(target, target)
|
||||
refnode += contnode or innernode(target, target) # type: ignore[call-arg]
|
||||
env.get_domain(domain).process_field_xref(refnode)
|
||||
return refnode
|
||||
lineno = -1
|
||||
|
@ -101,7 +101,7 @@ def register_role(name: str, role: RoleFunction) -> None:
|
||||
This modifies global state of docutils. So it is better to use this
|
||||
inside ``docutils_namespace()`` to prevent side-effects.
|
||||
"""
|
||||
roles.register_local_role(name, role)
|
||||
roles.register_local_role(name, role) # type: ignore[arg-type]
|
||||
|
||||
|
||||
def unregister_role(name: str) -> None:
|
||||
@ -150,7 +150,7 @@ def patched_get_language() -> Generator[None, None, None]:
|
||||
return get_language(language_code)
|
||||
|
||||
try:
|
||||
docutils.languages.get_language = patched_get_language
|
||||
docutils.languages.get_language = patched_get_language # type: ignore[assignment]
|
||||
yield
|
||||
finally:
|
||||
# restore original implementations
|
||||
@ -174,7 +174,7 @@ def patched_rst_get_language() -> Generator[None, None, None]:
|
||||
return get_language(language_code)
|
||||
|
||||
try:
|
||||
docutils.parsers.rst.languages.get_language = patched_get_language
|
||||
docutils.parsers.rst.languages.get_language = patched_get_language # type: ignore[assignment]
|
||||
yield
|
||||
finally:
|
||||
# restore original implementations
|
||||
@ -201,7 +201,7 @@ def using_user_docutils_conf(confdir: str | None) -> Generator[None, None, None]
|
||||
def du19_footnotes() -> Generator[None, None, None]:
|
||||
def visit_footnote(self: HTMLTranslator, node: Element) -> None:
|
||||
label_style = self.settings.footnote_references
|
||||
if not isinstance(node.previous_sibling(), type(node)): # type: ignore[attr-defined]
|
||||
if not isinstance(node.previous_sibling(), type(node)):
|
||||
self.body.append(f'<aside class="footnote-list {label_style}">\n')
|
||||
self.body.append(self.starttag(node, 'aside',
|
||||
classes=[node.tagname, label_style],
|
||||
@ -263,8 +263,8 @@ class CustomReSTDispatcher:
|
||||
self.directive_func = directives.directive
|
||||
self.role_func = roles.role
|
||||
|
||||
directives.directive = self.directive
|
||||
roles.role = self.role
|
||||
directives.directive = self.directive # type: ignore[assignment]
|
||||
roles.role = self.role # type: ignore[assignment]
|
||||
|
||||
def disable(self) -> None:
|
||||
directives.directive = self.directive_func
|
||||
@ -383,7 +383,7 @@ def switch_source_input(state: State, content: StringList) -> Generator[None, No
|
||||
gsal = state.memo.reporter.get_source_and_line # type: ignore[attr-defined]
|
||||
|
||||
# replace it by new one
|
||||
state_machine = StateMachine([], None) # type: ignore[arg-type]
|
||||
state_machine: StateMachine[None] = StateMachine([], None) # type: ignore[arg-type]
|
||||
state_machine.input_lines = content
|
||||
state.memo.reporter.get_source_and_line = state_machine.get_source_and_line # type: ignore[attr-defined] # NoQA: E501
|
||||
|
||||
|
@ -80,7 +80,7 @@ def copy_asset(source: str | os.PathLike[str], destination: str | os.PathLike[st
|
||||
return
|
||||
|
||||
for root, dirs, files in os.walk(source, followlinks=True):
|
||||
reldir = relative_path(source, root) # type: ignore[arg-type]
|
||||
reldir = relative_path(source, root)
|
||||
for dir in dirs.copy():
|
||||
if excluded(posixpath.join(reldir, dir)):
|
||||
dirs.remove(dir)
|
||||
|
@ -5,7 +5,7 @@ from __future__ import annotations
|
||||
import contextlib
|
||||
import re
|
||||
import unicodedata
|
||||
from typing import TYPE_CHECKING, Any, Callable, Generic, TypeVar
|
||||
from typing import TYPE_CHECKING, Any, Callable, Generic, TypeVar, cast
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.nodes import Node
|
||||
@ -93,7 +93,8 @@ class NodeMatcher(Generic[N]):
|
||||
While the `NodeMatcher` object can be used as an argument to `Node.findall`, doing so
|
||||
confounds type checkers' ability to determine the return type of the iterator.
|
||||
"""
|
||||
return node.findall(self)
|
||||
for found in node.findall(self):
|
||||
yield cast(N, found)
|
||||
|
||||
|
||||
def get_full_module_name(node: Node) -> str:
|
||||
@ -137,7 +138,7 @@ def apply_source_workaround(node: Element) -> None:
|
||||
get_full_module_name(node), repr_domxml(node))
|
||||
definition_list_item = node.parent
|
||||
node.source = definition_list_item.source
|
||||
node.line = definition_list_item.line - 1
|
||||
node.line = definition_list_item.line - 1 # type: ignore[operator]
|
||||
node.rawsource = node.astext() # set 'classifier1' (or 'classifier2')
|
||||
elif isinstance(node, nodes.classifier) and not node.source:
|
||||
# docutils-0.15 fills in rawsource attribute, but not in source.
|
||||
@ -236,7 +237,7 @@ def is_translatable(node: Node) -> bool:
|
||||
return False
|
||||
return True
|
||||
|
||||
return isinstance(node, nodes.meta) # type: ignore[attr-defined]
|
||||
return isinstance(node, nodes.meta)
|
||||
|
||||
|
||||
LITERAL_TYPE_NODES = (
|
||||
@ -252,10 +253,10 @@ IMAGE_TYPE_NODES = (
|
||||
|
||||
def extract_messages(doctree: Element) -> Iterable[tuple[Element, str]]:
|
||||
"""Extract translatable messages from a document tree."""
|
||||
for node in doctree.findall(is_translatable): # type: Element
|
||||
for node in doctree.findall(is_translatable):
|
||||
if isinstance(node, addnodes.translatable):
|
||||
for msg in node.extract_original_messages():
|
||||
yield node, msg
|
||||
yield node, msg # type: ignore[misc]
|
||||
continue
|
||||
if isinstance(node, LITERAL_TYPE_NODES):
|
||||
msg = node.rawsource
|
||||
@ -269,14 +270,14 @@ def extract_messages(doctree: Element) -> Iterable[tuple[Element, str]]:
|
||||
msg = f'.. image:: {image_uri}'
|
||||
else:
|
||||
msg = ''
|
||||
elif isinstance(node, nodes.meta): # type: ignore[attr-defined]
|
||||
elif isinstance(node, nodes.meta):
|
||||
msg = node["content"]
|
||||
else:
|
||||
msg = node.rawsource.replace('\n', ' ').strip()
|
||||
msg = node.rawsource.replace('\n', ' ').strip() # type: ignore[attr-defined]
|
||||
|
||||
# XXX nodes rendering empty are likely a bug in sphinx.addnodes
|
||||
if msg:
|
||||
yield node, msg
|
||||
yield node, msg # type: ignore[misc]
|
||||
|
||||
|
||||
def get_node_source(node: Element) -> str:
|
||||
|
@ -5,11 +5,11 @@ from __future__ import annotations
|
||||
import re
|
||||
from collections import defaultdict
|
||||
from contextlib import contextmanager
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING, cast
|
||||
from unicodedata import east_asian_width
|
||||
|
||||
from docutils.parsers.rst import roles
|
||||
from docutils.parsers.rst.languages import en as english
|
||||
from docutils.parsers.rst.languages import en as english # type: ignore[attr-defined]
|
||||
from docutils.parsers.rst.states import Body
|
||||
from docutils.utils import Reporter
|
||||
from jinja2 import Environment, pass_environment
|
||||
@ -65,7 +65,7 @@ def default_role(docname: str, name: str) -> Generator[None, None, None]:
|
||||
if name:
|
||||
dummy_reporter = Reporter('', 4, 4)
|
||||
role_fn, _ = roles.role(name, english, 0, dummy_reporter)
|
||||
if role_fn: # type: ignore[truthy-function]
|
||||
if role_fn:
|
||||
docutils.register_role('', role_fn) # type: ignore[arg-type]
|
||||
else:
|
||||
logger.warning(__('default role %s not found'), name, location=docname)
|
||||
@ -103,6 +103,7 @@ def append_epilog(content: StringList, epilog: str) -> None:
|
||||
if epilog:
|
||||
if len(content) > 0:
|
||||
source, lineno = content.info(-1)
|
||||
lineno = cast(int, lineno) # lineno will never be None, since len(content) > 0
|
||||
else:
|
||||
source = '<generated>'
|
||||
lineno = 0
|
||||
|
@ -338,7 +338,7 @@ class HTML5Translator(SphinxTranslator, BaseTranslator):
|
||||
self.depart_reference(node)
|
||||
|
||||
# overwritten -- we don't want source comments to show up in the HTML
|
||||
def visit_comment(self, node: Element) -> None: # type: ignore[override]
|
||||
def visit_comment(self, node: Element) -> None:
|
||||
raise nodes.SkipNode
|
||||
|
||||
# overwritten
|
||||
|
@ -2121,7 +2121,7 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
self.body.append('}}$')
|
||||
|
||||
def visit_inline(self, node: Element) -> None:
|
||||
classes = node.get('classes', [])
|
||||
classes = node.get('classes', []) # type: ignore[var-annotated]
|
||||
if classes == ['menuselection']:
|
||||
self.body.append(r'\sphinxmenuselection{')
|
||||
self.context.append('}')
|
||||
@ -2153,12 +2153,12 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
pass
|
||||
|
||||
def visit_container(self, node: Element) -> None:
|
||||
classes = node.get('classes', [])
|
||||
classes = node.get('classes', []) # type: ignore[var-annotated]
|
||||
for c in classes:
|
||||
self.body.append('\n\\begin{sphinxuseclass}{%s}' % c)
|
||||
|
||||
def depart_container(self, node: Element) -> None:
|
||||
classes = node.get('classes', [])
|
||||
classes = node.get('classes', []) # type: ignore[var-annotated]
|
||||
for _c in classes:
|
||||
self.body.append('\n\\end{sphinxuseclass}')
|
||||
|
||||
|
@ -245,7 +245,7 @@ class ManualPageTranslator(SphinxTranslator, BaseTranslator):
|
||||
super().visit_term(node)
|
||||
|
||||
# overwritten -- we don't want source comments to show up
|
||||
def visit_comment(self, node: Element) -> None: # type: ignore[override]
|
||||
def visit_comment(self, node: Element) -> None:
|
||||
raise nodes.SkipNode
|
||||
|
||||
# overwritten -- added ensure_eol()
|
||||
@ -316,7 +316,7 @@ class ManualPageTranslator(SphinxTranslator, BaseTranslator):
|
||||
self.body.append(self.defs['reference'][0])
|
||||
# avoid repeating escaping code... fine since
|
||||
# visit_Text calls astext() and only works on that afterwards
|
||||
self.visit_Text(node) # type: ignore[arg-type]
|
||||
self.visit_Text(node)
|
||||
self.body.append(self.defs['reference'][1])
|
||||
|
||||
if uri.startswith(('mailto:', 'http:', 'https:', 'ftp:')):
|
||||
|
@ -281,7 +281,7 @@ class TexinfoTranslator(SphinxTranslator):
|
||||
for name, content in self.indices]
|
||||
# each section is also a node
|
||||
for section in self.document.findall(nodes.section):
|
||||
title = cast(nodes.TextElement, section.next_node(nodes.Titular))
|
||||
title = cast(nodes.TextElement, section.next_node(nodes.Titular)) # type: ignore[type-var]
|
||||
name = title.astext() if title else '<untitled>'
|
||||
section['node_name'] = add_node_name(name)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user