mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge branch '2.0'
This commit is contained in:
commit
c18dcf08f9
@ -243,21 +243,23 @@ inserting them into the page source under a suitable :rst:dir:`py:module`,
|
||||
These work exactly like :rst:dir:`autoclass` etc.,
|
||||
but do not offer the options used for automatic member documentation.
|
||||
|
||||
:rst:dir:`autodata` and :rst:dir:`autoattribute` support
|
||||
the ``annotation`` option.
|
||||
Without this option, the representation of the object
|
||||
will be shown in the documentation.
|
||||
When the option is given without arguments,
|
||||
only the name of the object will be printed::
|
||||
:rst:dir:`autodata` and :rst:dir:`autoattribute` support the ``annotation``
|
||||
option. The option controls how the value of variable is shown. If specified
|
||||
without arguments, only the name of the variable will be printed, and its value
|
||||
is not shown::
|
||||
|
||||
.. autodata:: CD_DRIVE
|
||||
:annotation:
|
||||
|
||||
You can tell sphinx what should be printed after the name::
|
||||
If the option specified with arguments, it is printed after the name as a value
|
||||
of the variable::
|
||||
|
||||
.. autodata:: CD_DRIVE
|
||||
:annotation: = your CD device name
|
||||
|
||||
By default, without ``annotation`` option, Sphinx tries to obtain the value of
|
||||
the variable and print it after the name.
|
||||
|
||||
For module data members and class attributes, documentation can either be put
|
||||
into a comment with special formatting (using a ``#:`` to start the comment
|
||||
instead of just ``#``), or in a docstring *after* the definition. Comments
|
||||
|
@ -10,21 +10,22 @@
|
||||
"""
|
||||
|
||||
import copy
|
||||
from typing import NamedTuple
|
||||
from typing import Any, Callable, Dict, Iterable, List, NamedTuple, Tuple, Type, Union
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.nodes import Element, Node, system_message
|
||||
from docutils.parsers.rst.states import Inliner
|
||||
|
||||
from sphinx.addnodes import pending_xref
|
||||
from sphinx.errors import SphinxError
|
||||
from sphinx.locale import _
|
||||
from sphinx.roles import XRefRole
|
||||
from sphinx.util.typing import RoleFunction
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Any, Callable, Dict, Iterable, List, Tuple, Type, Union # NOQA
|
||||
from docutils import nodes # NOQA
|
||||
from docutils.parsers.rst.states import Inliner # NOQA
|
||||
from sphinx import addnodes # NOQA
|
||||
from sphinx.builders import Builder # NOQA
|
||||
from sphinx.environment import BuildEnvironment # NOQA
|
||||
from sphinx.roles import XRefRole # NOQA
|
||||
from sphinx.util.typing import RoleFunction # NOQA
|
||||
from sphinx.builders import Builder
|
||||
from sphinx.environment import BuildEnvironment
|
||||
|
||||
|
||||
class ObjType:
|
||||
@ -46,8 +47,7 @@ class ObjType:
|
||||
'searchprio': 1,
|
||||
}
|
||||
|
||||
def __init__(self, lname, *roles, **attrs):
|
||||
# type: (str, Any, Any) -> None
|
||||
def __init__(self, lname: str, *roles, **attrs) -> None:
|
||||
self.lname = lname
|
||||
self.roles = roles # type: Tuple
|
||||
self.attrs = self.known_attrs.copy() # type: Dict
|
||||
@ -82,15 +82,14 @@ class Index:
|
||||
localname = None # type: str
|
||||
shortname = None # type: str
|
||||
|
||||
def __init__(self, domain):
|
||||
# type: (Domain) -> None
|
||||
def __init__(self, domain: "Domain") -> None:
|
||||
if self.name is None or self.localname is None:
|
||||
raise SphinxError('Index subclass %s has no valid name or localname'
|
||||
% self.__class__.__name__)
|
||||
self.domain = domain
|
||||
|
||||
def generate(self, docnames=None):
|
||||
# type: (Iterable[str]) -> Tuple[List[Tuple[str, List[IndexEntry]]], bool]
|
||||
def generate(self, docnames: Iterable[str] = None
|
||||
) -> Tuple[List[Tuple[str, List[IndexEntry]]], bool]:
|
||||
"""Get entries for the index.
|
||||
|
||||
If ``docnames`` is given, restrict to entries referring to these
|
||||
@ -181,7 +180,7 @@ class Domain:
|
||||
#: role name -> a warning message if reference is missing
|
||||
dangling_warnings = {} # type: Dict[str, str]
|
||||
#: node_class -> (enum_node_type, title_getter)
|
||||
enumerable_nodes = {} # type: Dict[Type[nodes.Node], Tuple[str, Callable]]
|
||||
enumerable_nodes = {} # type: Dict[Type[Node], Tuple[str, Callable]]
|
||||
|
||||
#: data value for a fresh environment
|
||||
initial_data = {} # type: Dict
|
||||
@ -190,8 +189,7 @@ class Domain:
|
||||
#: data version, bump this when the format of `self.data` changes
|
||||
data_version = 0
|
||||
|
||||
def __init__(self, env):
|
||||
# type: (BuildEnvironment) -> None
|
||||
def __init__(self, env: "BuildEnvironment") -> None:
|
||||
self.env = env # type: BuildEnvironment
|
||||
self._role_cache = {} # type: Dict[str, Callable]
|
||||
self._directive_cache = {} # type: Dict[str, Callable]
|
||||
@ -220,8 +218,7 @@ class Domain:
|
||||
self.objtypes_for_role = self._role2type.get # type: Callable[[str], List[str]]
|
||||
self.role_for_objtype = self._type2role.get # type: Callable[[str], str]
|
||||
|
||||
def add_object_type(self, name, objtype):
|
||||
# type: (str, ObjType) -> None
|
||||
def add_object_type(self, name: str, objtype: ObjType) -> None:
|
||||
"""Add an object type."""
|
||||
self.object_types[name] = objtype
|
||||
if objtype.roles:
|
||||
@ -232,8 +229,7 @@ class Domain:
|
||||
for role in objtype.roles:
|
||||
self._role2type.setdefault(role, []).append(name)
|
||||
|
||||
def role(self, name):
|
||||
# type: (str) -> RoleFunction
|
||||
def role(self, name: str) -> RoleFunction:
|
||||
"""Return a role adapter function that always gives the registered
|
||||
role its full name ('domain:name') as the first argument.
|
||||
"""
|
||||
@ -243,15 +239,15 @@ class Domain:
|
||||
return None
|
||||
fullname = '%s:%s' % (self.name, name)
|
||||
|
||||
def role_adapter(typ, rawtext, text, lineno, inliner, options={}, content=[]):
|
||||
# type: (str, str, str, int, Inliner, Dict, List[str]) -> Tuple[List[nodes.Node], List[nodes.system_message]] # NOQA
|
||||
def role_adapter(typ: str, rawtext: str, text: str, lineno: int,
|
||||
inliner: Inliner, options: Dict = {}, content: List[str] = []
|
||||
) -> Tuple[List[Node], List[system_message]]:
|
||||
return self.roles[name](fullname, rawtext, text, lineno,
|
||||
inliner, options, content)
|
||||
self._role_cache[name] = role_adapter
|
||||
return role_adapter
|
||||
|
||||
def directive(self, name):
|
||||
# type: (str) -> Callable
|
||||
def directive(self, name: str) -> Callable:
|
||||
"""Return a directive adapter class that always gives the registered
|
||||
directive its full name ('domain:name') as ``self.name``.
|
||||
"""
|
||||
@ -263,8 +259,7 @@ class Domain:
|
||||
BaseDirective = self.directives[name]
|
||||
|
||||
class DirectiveAdapter(BaseDirective): # type: ignore
|
||||
def run(self):
|
||||
# type: () -> List[nodes.Node]
|
||||
def run(self) -> List[Node]:
|
||||
self.name = fullname
|
||||
return super().run()
|
||||
self._directive_cache[name] = DirectiveAdapter
|
||||
@ -272,13 +267,11 @@ class Domain:
|
||||
|
||||
# methods that should be overwritten
|
||||
|
||||
def clear_doc(self, docname):
|
||||
# type: (str) -> None
|
||||
def clear_doc(self, docname: str) -> None:
|
||||
"""Remove traces of a document in the domain-specific inventories."""
|
||||
pass
|
||||
|
||||
def merge_domaindata(self, docnames, otherdata):
|
||||
# type: (List[str], Dict) -> None
|
||||
def merge_domaindata(self, docnames: List[str], otherdata: Dict) -> None:
|
||||
"""Merge in data regarding *docnames* from a different domaindata
|
||||
inventory (coming from a subprocess in parallel builds).
|
||||
"""
|
||||
@ -286,26 +279,24 @@ class Domain:
|
||||
'to be able to do parallel builds!' %
|
||||
self.__class__)
|
||||
|
||||
def process_doc(self, env, docname, document):
|
||||
# type: (BuildEnvironment, str, nodes.document) -> None
|
||||
def process_doc(self, env: "BuildEnvironment", docname: str,
|
||||
document: nodes.document) -> None:
|
||||
"""Process a document after it is read by the environment."""
|
||||
pass
|
||||
|
||||
def check_consistency(self):
|
||||
# type: () -> None
|
||||
def check_consistency(self) -> None:
|
||||
"""Do consistency checks (**experimental**)."""
|
||||
pass
|
||||
|
||||
def process_field_xref(self, pnode):
|
||||
# type: (addnodes.pending_xref) -> None
|
||||
def process_field_xref(self, pnode: pending_xref) -> None:
|
||||
"""Process a pending xref created in a doc field.
|
||||
For example, attach information about the current scope.
|
||||
"""
|
||||
pass
|
||||
|
||||
def resolve_xref(self, env, fromdocname, builder,
|
||||
typ, target, node, contnode):
|
||||
# type: (BuildEnvironment, str, Builder, str, str, addnodes.pending_xref, nodes.Element) -> nodes.Element # NOQA
|
||||
def resolve_xref(self, env: "BuildEnvironment", fromdocname: str, builder: "Builder",
|
||||
typ: str, target: str, node: pending_xref, contnode: Element
|
||||
) -> Element:
|
||||
"""Resolve the pending_xref *node* with the given *typ* and *target*.
|
||||
|
||||
This method should return a new node, to replace the xref node,
|
||||
@ -321,8 +312,9 @@ class Domain:
|
||||
"""
|
||||
pass
|
||||
|
||||
def resolve_any_xref(self, env, fromdocname, builder, target, node, contnode):
|
||||
# type: (BuildEnvironment, str, Builder, str, addnodes.pending_xref, nodes.Element) -> List[Tuple[str, nodes.Element]] # NOQA
|
||||
def resolve_any_xref(self, env: "BuildEnvironment", fromdocname: str, builder: "Builder",
|
||||
target: str, node: pending_xref, contnode: Element
|
||||
) -> List[Tuple[str, Element]]:
|
||||
"""Resolve the pending_xref *node* with the given *target*.
|
||||
|
||||
The reference comes from an "any" or similar role, which means that we
|
||||
@ -338,8 +330,7 @@ class Domain:
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def get_objects(self):
|
||||
# type: () -> Iterable[Tuple[str, str, str, str, str, int]]
|
||||
def get_objects(self) -> Iterable[Tuple[str, str, str, str, str, int]]:
|
||||
"""Return an iterable of "object descriptions".
|
||||
|
||||
Object descriptions are tuples with six items:
|
||||
@ -374,20 +365,17 @@ class Domain:
|
||||
"""
|
||||
return []
|
||||
|
||||
def get_type_name(self, type, primary=False):
|
||||
# type: (ObjType, bool) -> str
|
||||
def get_type_name(self, type: ObjType, primary: bool = False) -> str:
|
||||
"""Return full name for given ObjType."""
|
||||
if primary:
|
||||
return type.lname
|
||||
return _('%s %s') % (self.label, type.lname)
|
||||
|
||||
def get_enumerable_node_type(self, node):
|
||||
# type: (nodes.Node) -> str
|
||||
def get_enumerable_node_type(self, node: Node) -> str:
|
||||
"""Get type of enumerable nodes (experimental)."""
|
||||
enum_node_type, _ = self.enumerable_nodes.get(node.__class__, (None, None))
|
||||
return enum_node_type
|
||||
|
||||
def get_full_qualified_name(self, node):
|
||||
# type: (nodes.Element) -> str
|
||||
def get_full_qualified_name(self, node: Element) -> str:
|
||||
"""Return full qualified name for given node."""
|
||||
return None
|
||||
|
@ -10,24 +10,23 @@
|
||||
|
||||
import re
|
||||
import string
|
||||
from typing import Any, Dict, Iterator, List, Tuple
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.nodes import Element
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx.addnodes import pending_xref, desc_signature
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.builders import Builder
|
||||
from sphinx.directives import ObjectDescription
|
||||
from sphinx.domains import Domain, ObjType
|
||||
from sphinx.environment import BuildEnvironment
|
||||
from sphinx.locale import _
|
||||
from sphinx.roles import XRefRole
|
||||
from sphinx.util.docfields import Field, TypedField
|
||||
from sphinx.util.nodes import make_refnode
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Any, Dict, Iterator, List, Tuple # NOQA
|
||||
from sphinx.application import Sphinx # NOQA
|
||||
from sphinx.builders import Builder # NOQA
|
||||
from sphinx.environment import BuildEnvironment # NOQA
|
||||
|
||||
|
||||
# RE to split at word boundaries
|
||||
wsplit_re = re.compile(r'(\W+)')
|
||||
@ -79,23 +78,20 @@ class CObject(ObjectDescription):
|
||||
'struct', '_Bool',
|
||||
}
|
||||
|
||||
def _parse_type(self, node, ctype):
|
||||
# type: (nodes.Element, str) -> None
|
||||
def _parse_type(self, node: Element, ctype: str) -> None:
|
||||
# add cross-ref nodes for all words
|
||||
for part in [_f for _f in wsplit_re.split(ctype) if _f]:
|
||||
tnode = nodes.Text(part, part)
|
||||
if part[0] in string.ascii_letters + '_' and \
|
||||
part not in self.stopwords:
|
||||
pnode = addnodes.pending_xref(
|
||||
'', refdomain='c', reftype='type', reftarget=part,
|
||||
modname=None, classname=None)
|
||||
pnode = pending_xref('', refdomain='c', reftype='type', reftarget=part,
|
||||
modname=None, classname=None)
|
||||
pnode += tnode
|
||||
node += pnode
|
||||
else:
|
||||
node += tnode
|
||||
|
||||
def _parse_arglist(self, arglist):
|
||||
# type: (str) -> Iterator[str]
|
||||
def _parse_arglist(self, arglist: str) -> Iterator[str]:
|
||||
while True:
|
||||
m = c_funcptr_arg_sig_re.match(arglist)
|
||||
if m:
|
||||
@ -113,8 +109,7 @@ class CObject(ObjectDescription):
|
||||
yield arglist
|
||||
break
|
||||
|
||||
def handle_signature(self, sig, signode):
|
||||
# type: (str, addnodes.desc_signature) -> str
|
||||
def handle_signature(self, sig: str, signode: desc_signature) -> str:
|
||||
"""Transform a C signature into RST nodes."""
|
||||
# first try the function pointer signature regex, it's more specific
|
||||
m = c_funcptr_sig_re.match(sig)
|
||||
@ -183,8 +178,7 @@ class CObject(ObjectDescription):
|
||||
signode += addnodes.desc_addname(const, const)
|
||||
return fullname
|
||||
|
||||
def get_index_text(self, name):
|
||||
# type: (str) -> str
|
||||
def get_index_text(self, name: str) -> str:
|
||||
if self.objtype == 'function':
|
||||
return _('%s (C function)') % name
|
||||
elif self.objtype == 'member':
|
||||
@ -198,8 +192,7 @@ class CObject(ObjectDescription):
|
||||
else:
|
||||
return ''
|
||||
|
||||
def add_target_and_index(self, name, sig, signode):
|
||||
# type: (str, str, addnodes.desc_signature) -> None
|
||||
def add_target_and_index(self, name: str, sig: str, signode: desc_signature) -> None:
|
||||
# for C API items we add a prefix since names are usually not qualified
|
||||
# by a module name and so easily clash with e.g. section titles
|
||||
targetname = 'c.' + name
|
||||
@ -221,23 +214,21 @@ class CObject(ObjectDescription):
|
||||
self.indexnode['entries'].append(('single', indextext,
|
||||
targetname, '', None))
|
||||
|
||||
def before_content(self):
|
||||
# type: () -> None
|
||||
def before_content(self) -> None:
|
||||
self.typename_set = False
|
||||
if self.name == 'c:type':
|
||||
if self.names:
|
||||
self.env.ref_context['c:type'] = self.names[0]
|
||||
self.typename_set = True
|
||||
|
||||
def after_content(self):
|
||||
# type: () -> None
|
||||
def after_content(self) -> None:
|
||||
if self.typename_set:
|
||||
self.env.ref_context.pop('c:type', None)
|
||||
|
||||
|
||||
class CXRefRole(XRefRole):
|
||||
def process_link(self, env, refnode, has_explicit_title, title, target):
|
||||
# type: (BuildEnvironment, nodes.Element, bool, str, str) -> Tuple[str, str]
|
||||
def process_link(self, env: BuildEnvironment, refnode: Element,
|
||||
has_explicit_title: bool, title: str, target: str) -> Tuple[str, str]:
|
||||
if not has_explicit_title:
|
||||
target = target.lstrip('~') # only has a meaning for the title
|
||||
# if the first character is a tilde, don't display the module/class
|
||||
@ -280,22 +271,20 @@ class CDomain(Domain):
|
||||
'objects': {}, # fullname -> docname, objtype
|
||||
} # type: Dict[str, Dict[str, Tuple[str, Any]]]
|
||||
|
||||
def clear_doc(self, docname):
|
||||
# type: (str) -> None
|
||||
def clear_doc(self, docname: str) -> None:
|
||||
for fullname, (fn, _l) in list(self.data['objects'].items()):
|
||||
if fn == docname:
|
||||
del self.data['objects'][fullname]
|
||||
|
||||
def merge_domaindata(self, docnames, otherdata):
|
||||
# type: (List[str], Dict) -> None
|
||||
def merge_domaindata(self, docnames: List[str], otherdata: Dict) -> None:
|
||||
# XXX check duplicates
|
||||
for fullname, (fn, objtype) in otherdata['objects'].items():
|
||||
if fn in docnames:
|
||||
self.data['objects'][fullname] = (fn, objtype)
|
||||
|
||||
def resolve_xref(self, env, fromdocname, builder,
|
||||
typ, target, node, contnode):
|
||||
# type: (BuildEnvironment, str, Builder, str, str, addnodes.pending_xref, nodes.Element) -> nodes.Element # NOQA
|
||||
def resolve_xref(self, env: BuildEnvironment, fromdocname: str, builder: Builder,
|
||||
typ: str, target: str, node: pending_xref, contnode: Element
|
||||
) -> Element:
|
||||
# strip pointer asterisk
|
||||
target = target.rstrip(' *')
|
||||
# becase TypedField can generate xrefs
|
||||
@ -307,9 +296,9 @@ class CDomain(Domain):
|
||||
return make_refnode(builder, fromdocname, obj[0], 'c.' + target,
|
||||
contnode, target)
|
||||
|
||||
def resolve_any_xref(self, env, fromdocname, builder, target,
|
||||
node, contnode):
|
||||
# type: (BuildEnvironment, str, Builder, str, addnodes.pending_xref, nodes.Element) -> List[Tuple[str, nodes.Element]] # NOQA
|
||||
def resolve_any_xref(self, env: BuildEnvironment, fromdocname: str, builder: Builder,
|
||||
target: str, node: pending_xref, contnode: Element
|
||||
) -> List[Tuple[str, Element]]:
|
||||
# strip pointer asterisk
|
||||
target = target.rstrip(' *')
|
||||
if target not in self.data['objects']:
|
||||
@ -319,14 +308,12 @@ class CDomain(Domain):
|
||||
make_refnode(builder, fromdocname, obj[0], 'c.' + target,
|
||||
contnode, target))]
|
||||
|
||||
def get_objects(self):
|
||||
# type: () -> Iterator[Tuple[str, str, str, str, str, int]]
|
||||
def get_objects(self) -> Iterator[Tuple[str, str, str, str, str, int]]:
|
||||
for refname, (docname, type) in list(self.data['objects'].items()):
|
||||
yield (refname, refname, type, docname, 'c.' + refname, 1)
|
||||
|
||||
|
||||
def setup(app):
|
||||
# type: (Sphinx) -> Dict[str, Any]
|
||||
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||
app.add_domain(CDomain)
|
||||
|
||||
return {
|
||||
|
@ -9,9 +9,11 @@
|
||||
"""
|
||||
|
||||
from collections import namedtuple
|
||||
from typing import Any, Dict, List
|
||||
from typing import cast
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.nodes import Node
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx.domains import Domain
|
||||
@ -21,9 +23,8 @@ from sphinx.util.docutils import SphinxDirective
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Any, Dict, List # NOQA
|
||||
from sphinx.application import Sphinx # NOQA
|
||||
from sphinx.environment import BuildEnvironment # NOQA
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.environment import BuildEnvironment
|
||||
|
||||
|
||||
versionlabels = {
|
||||
@ -54,8 +55,7 @@ class VersionChange(SphinxDirective):
|
||||
final_argument_whitespace = True
|
||||
option_spec = {} # type: Dict
|
||||
|
||||
def run(self):
|
||||
# type: () -> List[nodes.Node]
|
||||
def run(self) -> List[Node]:
|
||||
node = addnodes.versionmodified()
|
||||
node.document = self.state.document
|
||||
self.set_source_info(node)
|
||||
@ -93,7 +93,7 @@ class VersionChange(SphinxDirective):
|
||||
domain = cast(ChangeSetDomain, self.env.get_domain('changeset'))
|
||||
domain.note_changeset(node)
|
||||
|
||||
ret = [node] # type: List[nodes.Node]
|
||||
ret = [node] # type: List[Node]
|
||||
ret += messages
|
||||
return ret
|
||||
|
||||
@ -108,15 +108,13 @@ class ChangeSetDomain(Domain):
|
||||
'changes': {}, # version -> list of ChangeSet
|
||||
} # type: Dict
|
||||
|
||||
def clear_doc(self, docname):
|
||||
# type: (str) -> None
|
||||
def clear_doc(self, docname: str) -> None:
|
||||
for version, changes in self.data['changes'].items():
|
||||
for changeset in changes[:]:
|
||||
if changeset.docname == docname:
|
||||
changes.remove(changeset)
|
||||
|
||||
def merge_domaindata(self, docnames, otherdata):
|
||||
# type: (List[str], Dict) -> None
|
||||
def merge_domaindata(self, docnames: List[str], otherdata: Dict) -> None:
|
||||
# XXX duplicates?
|
||||
for version, otherchanges in otherdata['changes'].items():
|
||||
changes = self.data['changes'].setdefault(version, [])
|
||||
@ -124,12 +122,10 @@ class ChangeSetDomain(Domain):
|
||||
if changeset.docname in docnames:
|
||||
changes.append(changeset)
|
||||
|
||||
def process_doc(self, env, docname, document):
|
||||
# type: (BuildEnvironment, str, nodes.document) -> None
|
||||
def process_doc(self, env: "BuildEnvironment", docname: str, document: nodes.document) -> None: # NOQA
|
||||
pass # nothing to do here. All changesets are registered on calling directive.
|
||||
|
||||
def note_changeset(self, node):
|
||||
# type: (addnodes.versionmodified) -> None
|
||||
def note_changeset(self, node: addnodes.versionmodified) -> None:
|
||||
version = node['version']
|
||||
module = self.env.ref_context.get('py:module')
|
||||
objname = self.env.temp_data.get('object')
|
||||
@ -137,13 +133,11 @@ class ChangeSetDomain(Domain):
|
||||
module, objname, node.astext())
|
||||
self.data['changes'].setdefault(version, []).append(changeset)
|
||||
|
||||
def get_changesets_for(self, version):
|
||||
# type: (str) -> List[ChangeSet]
|
||||
def get_changesets_for(self, version: str) -> List[ChangeSet]:
|
||||
return self.data['changes'].get(version, [])
|
||||
|
||||
|
||||
def setup(app):
|
||||
# type: (Sphinx) -> Dict[str, Any]
|
||||
def setup(app: "Sphinx") -> Dict[str, Any]:
|
||||
app.add_domain(ChangeSetDomain)
|
||||
app.add_directive('deprecated', VersionChange)
|
||||
app.add_directive('versionadded', VersionChange)
|
||||
|
@ -8,11 +8,13 @@
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
|
||||
from typing import Any, Dict, List, Set, Tuple
|
||||
from typing import cast
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.nodes import Element
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx.addnodes import pending_xref
|
||||
from sphinx.domains import Domain
|
||||
from sphinx.locale import __
|
||||
from sphinx.transforms import SphinxTransform
|
||||
@ -21,10 +23,10 @@ from sphinx.util.nodes import copy_source_info, make_refnode
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Any, Dict, List, Set, Tuple, Union # NOQA
|
||||
from sphinx.application import Sphinx # NOQA
|
||||
from sphinx.builders import Builder # NOQA
|
||||
from sphinx.environment import BuildEnvironment # NOQA
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.builders import Builder
|
||||
from sphinx.environment import BuildEnvironment
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -40,17 +42,14 @@ class CitationDomain(Domain):
|
||||
}
|
||||
|
||||
@property
|
||||
def citations(self):
|
||||
# type: () -> Dict[str, Tuple[str, str, int]]
|
||||
def citations(self) -> Dict[str, Tuple[str, str, int]]:
|
||||
return self.data.setdefault('citations', {})
|
||||
|
||||
@property
|
||||
def citation_refs(self):
|
||||
# type: () -> Dict[str, Set[str]]
|
||||
def citation_refs(self) -> Dict[str, Set[str]]:
|
||||
return self.data.setdefault('citation_refs', {})
|
||||
|
||||
def clear_doc(self, docname):
|
||||
# type: (str) -> None
|
||||
def clear_doc(self, docname: str) -> None:
|
||||
for key, (fn, _l, lineno) in list(self.citations.items()):
|
||||
if fn == docname:
|
||||
del self.citations[key]
|
||||
@ -60,8 +59,7 @@ class CitationDomain(Domain):
|
||||
elif docname in docnames:
|
||||
docnames.remove(docname)
|
||||
|
||||
def merge_domaindata(self, docnames, otherdata):
|
||||
# type: (List[str], Dict) -> None
|
||||
def merge_domaindata(self, docnames: List[str], otherdata: Dict) -> None:
|
||||
# XXX duplicates?
|
||||
for key, data in otherdata['citations'].items():
|
||||
if data[0] in docnames:
|
||||
@ -72,8 +70,7 @@ class CitationDomain(Domain):
|
||||
if docname in docnames:
|
||||
citation_refs.add(docname)
|
||||
|
||||
def note_citation(self, node):
|
||||
# type: (nodes.citation) -> None
|
||||
def note_citation(self, node: nodes.citation) -> None:
|
||||
label = node[0].astext()
|
||||
if label in self.citations:
|
||||
path = self.env.doc2path(self.citations[label][0])
|
||||
@ -81,20 +78,19 @@ class CitationDomain(Domain):
|
||||
location=node, type='ref', subtype='citation')
|
||||
self.citations[label] = (node['docname'], node['ids'][0], node.line)
|
||||
|
||||
def note_citation_reference(self, node):
|
||||
# type: (addnodes.pending_xref) -> None
|
||||
def note_citation_reference(self, node: pending_xref) -> None:
|
||||
docnames = self.citation_refs.setdefault(node['reftarget'], set())
|
||||
docnames.add(self.env.docname)
|
||||
|
||||
def check_consistency(self):
|
||||
# type: () -> None
|
||||
def check_consistency(self) -> None:
|
||||
for name, (docname, labelid, lineno) in self.citations.items():
|
||||
if name not in self.citation_refs:
|
||||
logger.warning(__('Citation [%s] is not referenced.'), name,
|
||||
type='ref', subtype='citation', location=(docname, lineno))
|
||||
|
||||
def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode):
|
||||
# type: (BuildEnvironment, str, Builder, str, str, addnodes.pending_xref, nodes.Element) -> nodes.Element # NOQA
|
||||
def resolve_xref(self, env: "BuildEnvironment", fromdocname: str, builder: "Builder",
|
||||
typ: str, target: str, node: pending_xref, contnode: Element
|
||||
) -> Element:
|
||||
docname, labelid, lineno = self.citations.get(target, ('', '', 0))
|
||||
if not docname:
|
||||
return None
|
||||
@ -102,8 +98,9 @@ class CitationDomain(Domain):
|
||||
return make_refnode(builder, fromdocname, docname,
|
||||
labelid, contnode)
|
||||
|
||||
def resolve_any_xref(self, env, fromdocname, builder, target, node, contnode):
|
||||
# type: (BuildEnvironment, str, Builder, str, addnodes.pending_xref, nodes.Element) -> List[Tuple[str, nodes.Element]] # NOQA
|
||||
def resolve_any_xref(self, env: "BuildEnvironment", fromdocname: str, builder: "Builder",
|
||||
target: str, node: pending_xref, contnode: Element
|
||||
) -> List[Tuple[str, Element]]:
|
||||
refnode = self.resolve_xref(env, fromdocname, builder, 'ref', target, node, contnode)
|
||||
if refnode is None:
|
||||
return []
|
||||
@ -115,8 +112,7 @@ class CitationDefinitionTransform(SphinxTransform):
|
||||
"""Mark citation definition labels as not smartquoted."""
|
||||
default_priority = 619
|
||||
|
||||
def apply(self, **kwargs):
|
||||
# type: (Any) -> None
|
||||
def apply(self, **kwargs) -> None:
|
||||
domain = cast(CitationDomain, self.env.get_domain('citation'))
|
||||
for node in self.document.traverse(nodes.citation):
|
||||
# register citation node to domain
|
||||
@ -135,16 +131,15 @@ class CitationReferenceTransform(SphinxTransform):
|
||||
"""
|
||||
default_priority = 619
|
||||
|
||||
def apply(self, **kwargs):
|
||||
# type: (Any) -> None
|
||||
def apply(self, **kwargs) -> None:
|
||||
domain = cast(CitationDomain, self.env.get_domain('citation'))
|
||||
for node in self.document.traverse(nodes.citation_reference):
|
||||
target = node.astext()
|
||||
ref = addnodes.pending_xref(target, refdomain='citation', reftype='ref',
|
||||
reftarget=target, refwarn=True,
|
||||
support_smartquotes=False,
|
||||
ids=node["ids"],
|
||||
classes=node.get('classes', []))
|
||||
ref = pending_xref(target, refdomain='citation', reftype='ref',
|
||||
reftarget=target, refwarn=True,
|
||||
support_smartquotes=False,
|
||||
ids=node["ids"],
|
||||
classes=node.get('classes', []))
|
||||
ref += nodes.inline(target, '[%s]' % target)
|
||||
copy_source_info(node, ref)
|
||||
node.replace_self(ref)
|
||||
@ -153,8 +148,7 @@ class CitationReferenceTransform(SphinxTransform):
|
||||
domain.note_citation_reference(ref)
|
||||
|
||||
|
||||
def setup(app):
|
||||
# type: (Sphinx) -> Dict[str, Any]
|
||||
def setup(app: "Sphinx") -> Dict[str, Any]:
|
||||
app.add_domain(CitationDomain)
|
||||
app.add_transform(CitationDefinitionTransform)
|
||||
app.add_transform(CitationReferenceTransform)
|
||||
|
@ -8,26 +8,26 @@
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
|
||||
from typing import Any, Dict, Iterator, List, Tuple
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.nodes import Element, Node
|
||||
from docutils.parsers.rst import directives
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx.addnodes import desc_signature, pending_xref
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.builders import Builder
|
||||
from sphinx.directives import ObjectDescription
|
||||
from sphinx.domains import Domain, ObjType
|
||||
from sphinx.domains.python import _pseudo_parse_arglist
|
||||
from sphinx.environment import BuildEnvironment
|
||||
from sphinx.locale import _
|
||||
from sphinx.roles import XRefRole
|
||||
from sphinx.util.docfields import Field, GroupedField, TypedField
|
||||
from sphinx.util.docutils import SphinxDirective
|
||||
from sphinx.util.nodes import make_refnode
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Any, Dict, Iterator, List, Tuple # NOQA
|
||||
from sphinx.application import Sphinx # NOQA
|
||||
from sphinx.builders import Builder # NOQA
|
||||
from sphinx.environment import BuildEnvironment # NOQA
|
||||
|
||||
|
||||
class JSObject(ObjectDescription):
|
||||
"""
|
||||
@ -44,8 +44,7 @@ class JSObject(ObjectDescription):
|
||||
#: based on directive nesting
|
||||
allow_nesting = False
|
||||
|
||||
def handle_signature(self, sig, signode):
|
||||
# type: (str, addnodes.desc_signature) -> Tuple[str, str]
|
||||
def handle_signature(self, sig: str, signode: desc_signature) -> Tuple[str, str]:
|
||||
"""Breaks down construct signatures
|
||||
|
||||
Parses out prefix and argument list from construct definition. The
|
||||
@ -98,8 +97,8 @@ class JSObject(ObjectDescription):
|
||||
_pseudo_parse_arglist(signode, arglist)
|
||||
return fullname, prefix
|
||||
|
||||
def add_target_and_index(self, name_obj, sig, signode):
|
||||
# type: (Tuple[str, str], str, addnodes.desc_signature) -> None
|
||||
def add_target_and_index(self, name_obj: Tuple[str, str], sig: str,
|
||||
signode: desc_signature) -> None:
|
||||
mod_name = self.env.ref_context.get('js:module')
|
||||
fullname = (mod_name and mod_name + '.' or '') + name_obj[0]
|
||||
if fullname not in self.state.document.ids:
|
||||
@ -122,8 +121,7 @@ class JSObject(ObjectDescription):
|
||||
fullname.replace('$', '_S_'),
|
||||
'', None))
|
||||
|
||||
def get_index_text(self, objectname, name_obj):
|
||||
# type: (str, Tuple[str, str]) -> str
|
||||
def get_index_text(self, objectname: str, name_obj: Tuple[str, str]) -> str:
|
||||
name, obj = name_obj
|
||||
if self.objtype == 'function':
|
||||
if not obj:
|
||||
@ -137,8 +135,7 @@ class JSObject(ObjectDescription):
|
||||
return _('%s (%s attribute)') % (name, obj)
|
||||
return ''
|
||||
|
||||
def before_content(self):
|
||||
# type: () -> None
|
||||
def before_content(self) -> None:
|
||||
"""Handle object nesting before content
|
||||
|
||||
:py:class:`JSObject` represents JavaScript language constructs. For
|
||||
@ -174,8 +171,7 @@ class JSObject(ObjectDescription):
|
||||
objects = self.env.ref_context.setdefault('js:objects', [])
|
||||
objects.append(prefix)
|
||||
|
||||
def after_content(self):
|
||||
# type: () -> None
|
||||
def after_content(self) -> None:
|
||||
"""Handle object de-nesting after content
|
||||
|
||||
If this class is a nestable object, removing the last nested class prefix
|
||||
@ -246,12 +242,11 @@ class JSModule(SphinxDirective):
|
||||
'noindex': directives.flag
|
||||
}
|
||||
|
||||
def run(self):
|
||||
# type: () -> List[nodes.Node]
|
||||
def run(self) -> List[Node]:
|
||||
mod_name = self.arguments[0].strip()
|
||||
self.env.ref_context['js:module'] = mod_name
|
||||
noindex = 'noindex' in self.options
|
||||
ret = [] # type: List[nodes.Node]
|
||||
ret = [] # type: List[Node]
|
||||
if not noindex:
|
||||
self.env.domaindata['js']['modules'][mod_name] = self.env.docname
|
||||
# Make a duplicate entry in 'objects' to facilitate searching for
|
||||
@ -269,8 +264,8 @@ class JSModule(SphinxDirective):
|
||||
|
||||
|
||||
class JSXRefRole(XRefRole):
|
||||
def process_link(self, env, refnode, has_explicit_title, title, target):
|
||||
# type: (BuildEnvironment, nodes.Element, bool, str, str) -> Tuple[str, str]
|
||||
def process_link(self, env: BuildEnvironment, refnode: Element,
|
||||
has_explicit_title: bool, title: str, target: str) -> Tuple[str, str]:
|
||||
# basically what sphinx.domains.python.PyXRefRole does
|
||||
refnode['js:object'] = env.ref_context.get('js:object')
|
||||
refnode['js:module'] = env.ref_context.get('js:module')
|
||||
@ -322,8 +317,7 @@ class JavaScriptDomain(Domain):
|
||||
'modules': {}, # mod_name -> docname
|
||||
} # type: Dict[str, Dict[str, Tuple[str, str]]]
|
||||
|
||||
def clear_doc(self, docname):
|
||||
# type: (str) -> None
|
||||
def clear_doc(self, docname: str) -> None:
|
||||
for fullname, (pkg_docname, _l) in list(self.data['objects'].items()):
|
||||
if pkg_docname == docname:
|
||||
del self.data['objects'][fullname]
|
||||
@ -331,8 +325,7 @@ class JavaScriptDomain(Domain):
|
||||
if pkg_docname == docname:
|
||||
del self.data['modules'][mod_name]
|
||||
|
||||
def merge_domaindata(self, docnames, otherdata):
|
||||
# type: (List[str], Dict) -> None
|
||||
def merge_domaindata(self, docnames: List[str], otherdata: Dict) -> None:
|
||||
# XXX check duplicates
|
||||
for fullname, (fn, objtype) in otherdata['objects'].items():
|
||||
if fn in docnames:
|
||||
@ -341,8 +334,8 @@ class JavaScriptDomain(Domain):
|
||||
if pkg_docname in docnames:
|
||||
self.data['modules'][mod_name] = pkg_docname
|
||||
|
||||
def find_obj(self, env, mod_name, prefix, name, typ, searchorder=0):
|
||||
# type: (BuildEnvironment, str, str, str, str, int) -> Tuple[str, Tuple[str, str]]
|
||||
def find_obj(self, env: BuildEnvironment, mod_name: str, prefix: str, name: str,
|
||||
typ: str, searchorder: int = 0) -> Tuple[str, Tuple[str, str]]:
|
||||
if name[-2:] == '()':
|
||||
name = name[:-2]
|
||||
objects = self.data['objects']
|
||||
@ -366,9 +359,9 @@ class JavaScriptDomain(Domain):
|
||||
|
||||
return newname, objects.get(newname)
|
||||
|
||||
def resolve_xref(self, env, fromdocname, builder, typ, target, node,
|
||||
contnode):
|
||||
# type: (BuildEnvironment, str, Builder, str, str, addnodes.pending_xref, nodes.Element) -> nodes.Element # NOQA
|
||||
def resolve_xref(self, env: BuildEnvironment, fromdocname: str, builder: Builder,
|
||||
typ: str, target: str, node: pending_xref, contnode: Element
|
||||
) -> Element:
|
||||
mod_name = node.get('js:module')
|
||||
prefix = node.get('js:object')
|
||||
searchorder = node.hasattr('refspecific') and 1 or 0
|
||||
@ -378,9 +371,9 @@ class JavaScriptDomain(Domain):
|
||||
return make_refnode(builder, fromdocname, obj[0],
|
||||
name.replace('$', '_S_'), contnode, name)
|
||||
|
||||
def resolve_any_xref(self, env, fromdocname, builder, target, node,
|
||||
contnode):
|
||||
# type: (BuildEnvironment, str, Builder, str, addnodes.pending_xref, nodes.Element) -> List[Tuple[str, nodes.Element]] # NOQA
|
||||
def resolve_any_xref(self, env: BuildEnvironment, fromdocname: str, builder: Builder,
|
||||
target: str, node: pending_xref, contnode: Element
|
||||
) -> List[Tuple[str, Element]]:
|
||||
mod_name = node.get('js:module')
|
||||
prefix = node.get('js:object')
|
||||
name, obj = self.find_obj(env, mod_name, prefix, target, None, 1)
|
||||
@ -390,14 +383,12 @@ class JavaScriptDomain(Domain):
|
||||
make_refnode(builder, fromdocname, obj[0],
|
||||
name.replace('$', '_S_'), contnode, name))]
|
||||
|
||||
def get_objects(self):
|
||||
# type: () -> Iterator[Tuple[str, str, str, str, str, int]]
|
||||
def get_objects(self) -> Iterator[Tuple[str, str, str, str, str, int]]:
|
||||
for refname, (docname, type) in list(self.data['objects'].items()):
|
||||
yield refname, refname, type, docname, \
|
||||
refname.replace('$', '_S_'), 1
|
||||
|
||||
def get_full_qualified_name(self, node):
|
||||
# type: (nodes.Element) -> str
|
||||
def get_full_qualified_name(self, node: Element) -> str:
|
||||
modname = node.get('js:module')
|
||||
prefix = node.get('js:object')
|
||||
target = node.get('reftarget')
|
||||
@ -407,8 +398,7 @@ class JavaScriptDomain(Domain):
|
||||
return '.'.join(filter(None, [modname, prefix, target]))
|
||||
|
||||
|
||||
def setup(app):
|
||||
# type: (Sphinx) -> Dict[str, Any]
|
||||
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||
app.add_domain(JavaScriptDomain)
|
||||
|
||||
return {
|
||||
|
@ -9,12 +9,16 @@
|
||||
"""
|
||||
|
||||
import warnings
|
||||
from typing import Any, Dict, Iterable, List, Tuple
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.nodes import Element, Node, system_message
|
||||
from docutils.nodes import make_id
|
||||
|
||||
from sphinx.addnodes import pending_xref
|
||||
from sphinx.deprecation import RemovedInSphinx40Warning
|
||||
from sphinx.domains import Domain
|
||||
from sphinx.environment import BuildEnvironment
|
||||
from sphinx.locale import __
|
||||
from sphinx.roles import XRefRole
|
||||
from sphinx.util import logging
|
||||
@ -22,18 +26,16 @@ from sphinx.util.nodes import make_refnode
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Any, Dict, Iterable, List, Tuple # NOQA
|
||||
from sphinx import addnodes # NOQA
|
||||
from sphinx.application import Sphinx # NOQA
|
||||
from sphinx.builders import Builder # NOQA
|
||||
from sphinx.environment import BuildEnvironment # NOQA
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.builders import Builder
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class MathReferenceRole(XRefRole):
|
||||
def result_nodes(self, document, env, node, is_ref):
|
||||
# type: (nodes.document, BuildEnvironment, nodes.Element, bool) -> Tuple[List[nodes.Node], List[nodes.system_message]] # NOQA
|
||||
def result_nodes(self, document: nodes.document, env: BuildEnvironment, node: Element,
|
||||
is_ref: bool) -> Tuple[List[Node], List[system_message]]:
|
||||
node['refdomain'] = 'math'
|
||||
return [node], []
|
||||
|
||||
@ -58,12 +60,10 @@ class MathDomain(Domain):
|
||||
}
|
||||
|
||||
@property
|
||||
def equations(self):
|
||||
# type: () -> Dict[str, Tuple[str, int]]
|
||||
def equations(self) -> Dict[str, Tuple[str, int]]:
|
||||
return self.data.setdefault('objects', {}) # labelid -> (docname, eqno)
|
||||
|
||||
def note_equation(self, docname, labelid, location=None):
|
||||
# type: (str, str, Any) -> None
|
||||
def note_equation(self, docname: str, labelid: str, location: Any = None) -> None:
|
||||
if labelid in self.equations:
|
||||
other = self.equations[labelid][0]
|
||||
logger.warning(__('duplicate label of equation %s, other instance in %s') %
|
||||
@ -71,31 +71,27 @@ class MathDomain(Domain):
|
||||
|
||||
self.equations[labelid] = (docname, self.env.new_serialno('eqno') + 1)
|
||||
|
||||
def get_equation_number_for(self, labelid):
|
||||
# type: (str) -> int
|
||||
def get_equation_number_for(self, labelid: str) -> int:
|
||||
if labelid in self.equations:
|
||||
return self.equations[labelid][1]
|
||||
else:
|
||||
return None
|
||||
|
||||
def process_doc(self, env, docname, document):
|
||||
# type: (BuildEnvironment, str, nodes.document) -> None
|
||||
def math_node(node):
|
||||
# type: (nodes.Node) -> bool
|
||||
def process_doc(self, env: BuildEnvironment, docname: str,
|
||||
document: nodes.document) -> None:
|
||||
def math_node(node: Node) -> bool:
|
||||
return isinstance(node, (nodes.math, nodes.math_block))
|
||||
|
||||
self.data['has_equations'][docname] = any(document.traverse(math_node))
|
||||
|
||||
def clear_doc(self, docname):
|
||||
# type: (str) -> None
|
||||
def clear_doc(self, docname: str) -> None:
|
||||
for equation_id, (doc, eqno) in list(self.equations.items()):
|
||||
if doc == docname:
|
||||
del self.equations[equation_id]
|
||||
|
||||
self.data['has_equations'].pop(docname, None)
|
||||
|
||||
def merge_domaindata(self, docnames, otherdata):
|
||||
# type: (Iterable[str], Dict) -> None
|
||||
def merge_domaindata(self, docnames: Iterable[str], otherdata: Dict) -> None:
|
||||
for labelid, (doc, eqno) in otherdata['objects'].items():
|
||||
if doc in docnames:
|
||||
self.equations[labelid] = (doc, eqno)
|
||||
@ -103,8 +99,9 @@ class MathDomain(Domain):
|
||||
for docname in docnames:
|
||||
self.data['has_equations'][docname] = otherdata['has_equations'][docname]
|
||||
|
||||
def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode):
|
||||
# type: (BuildEnvironment, str, Builder, str, str, addnodes.pending_xref, nodes.Element) -> nodes.Element # NOQA
|
||||
def resolve_xref(self, env: BuildEnvironment, fromdocname: str, builder: "Builder",
|
||||
typ: str, target: str, node: pending_xref, contnode: Element
|
||||
) -> Element:
|
||||
assert typ in ('eq', 'numref')
|
||||
docname, number = self.equations.get(target, (None, None))
|
||||
if docname:
|
||||
@ -131,20 +128,19 @@ class MathDomain(Domain):
|
||||
else:
|
||||
return None
|
||||
|
||||
def resolve_any_xref(self, env, fromdocname, builder, target, node, contnode):
|
||||
# type: (BuildEnvironment, str, Builder, str, addnodes.pending_xref, nodes.Element) -> List[Tuple[str, nodes.Element]] # NOQA
|
||||
def resolve_any_xref(self, env: BuildEnvironment, fromdocname: str, builder: "Builder",
|
||||
target: str, node: pending_xref, contnode: Element
|
||||
) -> List[Tuple[str, Element]]:
|
||||
refnode = self.resolve_xref(env, fromdocname, builder, 'eq', target, node, contnode)
|
||||
if refnode is None:
|
||||
return []
|
||||
else:
|
||||
return [('eq', refnode)]
|
||||
|
||||
def get_objects(self):
|
||||
# type: () -> List
|
||||
def get_objects(self) -> List:
|
||||
return []
|
||||
|
||||
def add_equation(self, env, docname, labelid):
|
||||
# type: (BuildEnvironment, str, str) -> int
|
||||
def add_equation(self, env: BuildEnvironment, docname: str, labelid: str) -> int:
|
||||
warnings.warn('MathDomain.add_equation() is deprecated.',
|
||||
RemovedInSphinx40Warning)
|
||||
if labelid in self.equations:
|
||||
@ -156,20 +152,17 @@ class MathDomain(Domain):
|
||||
self.equations[labelid] = (docname, eqno)
|
||||
return eqno
|
||||
|
||||
def get_next_equation_number(self, docname):
|
||||
# type: (str) -> int
|
||||
def get_next_equation_number(self, docname: str) -> int:
|
||||
warnings.warn('MathDomain.get_next_equation_number() is deprecated.',
|
||||
RemovedInSphinx40Warning)
|
||||
targets = [eq for eq in self.equations.values() if eq[0] == docname]
|
||||
return len(targets) + 1
|
||||
|
||||
def has_equations(self):
|
||||
# type: () -> bool
|
||||
def has_equations(self) -> bool:
|
||||
return any(self.data['has_equations'].values())
|
||||
|
||||
|
||||
def setup(app):
|
||||
# type: (Sphinx) -> Dict[str, Any]
|
||||
def setup(app: "Sphinx") -> Dict[str, Any]:
|
||||
app.add_domain(MathDomain)
|
||||
app.add_role('eq', MathReferenceRole(warn_dangling=True))
|
||||
|
||||
|
@ -10,29 +10,29 @@
|
||||
|
||||
import re
|
||||
import warnings
|
||||
from typing import Any, Dict, Iterable, Iterator, List, Tuple, Type
|
||||
from typing import cast
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.nodes import Element, Node
|
||||
from docutils.parsers.rst import directives
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx.addnodes import pending_xref, desc_signature
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.builders import Builder
|
||||
from sphinx.deprecation import RemovedInSphinx40Warning
|
||||
from sphinx.directives import ObjectDescription
|
||||
from sphinx.domains import Domain, ObjType, Index, IndexEntry
|
||||
from sphinx.environment import BuildEnvironment
|
||||
from sphinx.locale import _, __
|
||||
from sphinx.roles import XRefRole
|
||||
from sphinx.util import logging
|
||||
from sphinx.util.docfields import Field, GroupedField, TypedField
|
||||
from sphinx.util.docutils import SphinxDirective
|
||||
from sphinx.util.nodes import make_refnode
|
||||
from sphinx.util.typing import TextlikeNode
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Any, Dict, Iterable, Iterator, List, Tuple, Type # NOQA
|
||||
from sphinx.application import Sphinx # NOQA
|
||||
from sphinx.builders import Builder # NOQA
|
||||
from sphinx.environment import BuildEnvironment # NOQA
|
||||
from sphinx.util.typing import TextlikeNode # NOQA
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -58,8 +58,7 @@ pairindextypes = {
|
||||
}
|
||||
|
||||
|
||||
def _pseudo_parse_arglist(signode, arglist):
|
||||
# type: (addnodes.desc_signature, str) -> None
|
||||
def _pseudo_parse_arglist(signode: desc_signature, arglist: str) -> None:
|
||||
""""Parse" a list of arguments separated by commas.
|
||||
|
||||
Arguments can have "optional" annotations given by enclosing them in
|
||||
@ -67,7 +66,7 @@ def _pseudo_parse_arglist(signode, arglist):
|
||||
string literal (e.g. default argument value).
|
||||
"""
|
||||
paramlist = addnodes.desc_parameterlist()
|
||||
stack = [paramlist] # type: List[nodes.Element]
|
||||
stack = [paramlist] # type: List[Element]
|
||||
try:
|
||||
for argument in arglist.split(','):
|
||||
argument = argument.strip()
|
||||
@ -110,15 +109,9 @@ def _pseudo_parse_arglist(signode, arglist):
|
||||
# This override allows our inline type specifiers to behave like :class: link
|
||||
# when it comes to handling "." and "~" prefixes.
|
||||
class PyXrefMixin:
|
||||
def make_xref(self,
|
||||
rolename, # type: str
|
||||
domain, # type: str
|
||||
target, # type: str
|
||||
innernode=nodes.emphasis, # type: Type[TextlikeNode]
|
||||
contnode=None, # type: nodes.Node
|
||||
env=None, # type: BuildEnvironment
|
||||
):
|
||||
# type: (...) -> nodes.Node
|
||||
def make_xref(self, rolename: str, domain: str, target: str,
|
||||
innernode: Type[TextlikeNode] = nodes.emphasis,
|
||||
contnode: Node = None, env: BuildEnvironment = None) -> Node:
|
||||
result = super().make_xref(rolename, domain, target, # type: ignore
|
||||
innernode, contnode, env)
|
||||
result['refspecific'] = True
|
||||
@ -133,15 +126,9 @@ class PyXrefMixin:
|
||||
break
|
||||
return result
|
||||
|
||||
def make_xrefs(self,
|
||||
rolename, # type: str
|
||||
domain, # type: str
|
||||
target, # type: str
|
||||
innernode=nodes.emphasis, # type: Type[TextlikeNode]
|
||||
contnode=None, # type: nodes.Node
|
||||
env=None, # type: BuildEnvironment
|
||||
):
|
||||
# type: (...) -> List[nodes.Node]
|
||||
def make_xrefs(self, rolename: str, domain: str, target: str,
|
||||
innernode: Type[TextlikeNode] = nodes.emphasis,
|
||||
contnode: Node = None, env: BuildEnvironment = None) -> List[Node]:
|
||||
delims = r'(\s*[\[\]\(\),](?:\s*or\s)?\s*|\s+or\s+)'
|
||||
delims_re = re.compile(delims)
|
||||
sub_targets = re.split(delims, target)
|
||||
@ -163,9 +150,9 @@ class PyXrefMixin:
|
||||
|
||||
|
||||
class PyField(PyXrefMixin, Field):
|
||||
def make_xref(self, rolename, domain, target,
|
||||
innernode=nodes.emphasis, contnode=None, env=None):
|
||||
# type: (str, str, str, Type[TextlikeNode], nodes.Node, BuildEnvironment) -> nodes.Node # NOQA
|
||||
def make_xref(self, rolename: str, domain: str, target: str,
|
||||
innernode: Type[TextlikeNode] = nodes.emphasis,
|
||||
contnode: Node = None, env: BuildEnvironment = None) -> Node:
|
||||
if rolename == 'class' and target == 'None':
|
||||
# None is not a type, so use obj role instead.
|
||||
rolename = 'obj'
|
||||
@ -178,9 +165,9 @@ class PyGroupedField(PyXrefMixin, GroupedField):
|
||||
|
||||
|
||||
class PyTypedField(PyXrefMixin, TypedField):
|
||||
def make_xref(self, rolename, domain, target,
|
||||
innernode=nodes.emphasis, contnode=None, env=None):
|
||||
# type: (str, str, str, Type[TextlikeNode], nodes.Node, BuildEnvironment) -> nodes.Node # NOQA
|
||||
def make_xref(self, rolename: str, domain: str, target: str,
|
||||
innernode: Type[TextlikeNode] = nodes.emphasis,
|
||||
contnode: Node = None, env: BuildEnvironment = None) -> Node:
|
||||
if rolename == 'class' and target == 'None':
|
||||
# None is not a type, so use obj role instead.
|
||||
rolename = 'obj'
|
||||
@ -222,22 +209,19 @@ class PyObject(ObjectDescription):
|
||||
|
||||
allow_nesting = False
|
||||
|
||||
def get_signature_prefix(self, sig):
|
||||
# type: (str) -> str
|
||||
def get_signature_prefix(self, sig: str) -> str:
|
||||
"""May return a prefix to put before the object name in the
|
||||
signature.
|
||||
"""
|
||||
return ''
|
||||
|
||||
def needs_arglist(self):
|
||||
# type: () -> bool
|
||||
def needs_arglist(self) -> bool:
|
||||
"""May return true if an empty argument list is to be generated even if
|
||||
the document contains none.
|
||||
"""
|
||||
return False
|
||||
|
||||
def handle_signature(self, sig, signode):
|
||||
# type: (str, addnodes.desc_signature) -> Tuple[str, str]
|
||||
def handle_signature(self, sig: str, signode: desc_signature) -> Tuple[str, str]:
|
||||
"""Transform a Python signature into RST nodes.
|
||||
|
||||
Return (fully qualified name of the thing, classname if any).
|
||||
@ -311,13 +295,12 @@ class PyObject(ObjectDescription):
|
||||
|
||||
return fullname, prefix
|
||||
|
||||
def get_index_text(self, modname, name):
|
||||
# type: (str, Tuple[str, str]) -> str
|
||||
def get_index_text(self, modname: str, name: Tuple[str, str]) -> str:
|
||||
"""Return the text for the index entry of the object."""
|
||||
raise NotImplementedError('must be implemented in subclasses')
|
||||
|
||||
def add_target_and_index(self, name_cls, sig, signode):
|
||||
# type: (Tuple[str, str], str, addnodes.desc_signature) -> None
|
||||
def add_target_and_index(self, name_cls: Tuple[str, str], sig: str,
|
||||
signode: desc_signature) -> None:
|
||||
modname = self.options.get('module', self.env.ref_context.get('py:module'))
|
||||
fullname = (modname and modname + '.' or '') + name_cls[0]
|
||||
# note target
|
||||
@ -336,8 +319,7 @@ class PyObject(ObjectDescription):
|
||||
self.indexnode['entries'].append(('single', indextext,
|
||||
fullname, '', None))
|
||||
|
||||
def before_content(self):
|
||||
# type: () -> None
|
||||
def before_content(self) -> None:
|
||||
"""Handle object nesting before content
|
||||
|
||||
:py:class:`PyObject` represents Python language constructs. For
|
||||
@ -370,8 +352,7 @@ class PyObject(ObjectDescription):
|
||||
modules.append(self.env.ref_context.get('py:module'))
|
||||
self.env.ref_context['py:module'] = self.options['module']
|
||||
|
||||
def after_content(self):
|
||||
# type: () -> None
|
||||
def after_content(self) -> None:
|
||||
"""Handle object de-nesting after content
|
||||
|
||||
If this class is a nestable object, removing the last nested class prefix
|
||||
@ -402,19 +383,16 @@ class PyModulelevel(PyObject):
|
||||
Description of an object on module level (functions, data).
|
||||
"""
|
||||
|
||||
def run(self):
|
||||
# type: () -> List[nodes.Node]
|
||||
def run(self) -> List[Node]:
|
||||
warnings.warn('PyClassmember is deprecated.',
|
||||
RemovedInSphinx40Warning)
|
||||
|
||||
return super().run()
|
||||
|
||||
def needs_arglist(self):
|
||||
# type: () -> bool
|
||||
def needs_arglist(self) -> bool:
|
||||
return self.objtype == 'function'
|
||||
|
||||
def get_index_text(self, modname, name_cls):
|
||||
# type: (str, Tuple[str, str]) -> str
|
||||
def get_index_text(self, modname: str, name_cls: Tuple[str, str]) -> str:
|
||||
if self.objtype == 'function':
|
||||
if not modname:
|
||||
return _('%s() (built-in function)') % name_cls[0]
|
||||
@ -435,19 +413,16 @@ class PyFunction(PyObject):
|
||||
'async': directives.flag,
|
||||
})
|
||||
|
||||
def get_signature_prefix(self, sig):
|
||||
# type: (str) -> str
|
||||
def get_signature_prefix(self, sig: str) -> str:
|
||||
if 'async' in self.options:
|
||||
return 'async '
|
||||
else:
|
||||
return ''
|
||||
|
||||
def needs_arglist(self):
|
||||
# type: () -> bool
|
||||
def needs_arglist(self) -> bool:
|
||||
return True
|
||||
|
||||
def get_index_text(self, modname, name_cls):
|
||||
# type: (str, Tuple[str, str]) -> str
|
||||
def get_index_text(self, modname: str, name_cls: Tuple[str, str]) -> str:
|
||||
name, cls = name_cls
|
||||
if modname:
|
||||
return _('%s() (in module %s)') % (name, modname)
|
||||
@ -458,8 +433,7 @@ class PyFunction(PyObject):
|
||||
class PyVariable(PyObject):
|
||||
"""Description of a variable."""
|
||||
|
||||
def get_index_text(self, modname, name_cls):
|
||||
# type: (str, Tuple[str, str]) -> str
|
||||
def get_index_text(self, modname: str, name_cls: Tuple[str, str]) -> str:
|
||||
name, cls = name_cls
|
||||
if modname:
|
||||
return _('%s (in module %s)') % (name, modname)
|
||||
@ -474,12 +448,10 @@ class PyClasslike(PyObject):
|
||||
|
||||
allow_nesting = True
|
||||
|
||||
def get_signature_prefix(self, sig):
|
||||
# type: (str) -> str
|
||||
def get_signature_prefix(self, sig: str) -> str:
|
||||
return self.objtype + ' '
|
||||
|
||||
def get_index_text(self, modname, name_cls):
|
||||
# type: (str, Tuple[str, str]) -> str
|
||||
def get_index_text(self, modname: str, name_cls: Tuple[str, str]) -> str:
|
||||
if self.objtype == 'class':
|
||||
if not modname:
|
||||
return _('%s (built-in class)') % name_cls[0]
|
||||
@ -495,27 +467,23 @@ class PyClassmember(PyObject):
|
||||
Description of a class member (methods, attributes).
|
||||
"""
|
||||
|
||||
def run(self):
|
||||
# type: () -> List[nodes.Node]
|
||||
def run(self) -> List[Node]:
|
||||
warnings.warn('PyClassmember is deprecated.',
|
||||
RemovedInSphinx40Warning)
|
||||
|
||||
return super().run()
|
||||
|
||||
def needs_arglist(self):
|
||||
# type: () -> bool
|
||||
def needs_arglist(self) -> bool:
|
||||
return self.objtype.endswith('method')
|
||||
|
||||
def get_signature_prefix(self, sig):
|
||||
# type: (str) -> str
|
||||
def get_signature_prefix(self, sig: str) -> str:
|
||||
if self.objtype == 'staticmethod':
|
||||
return 'static '
|
||||
elif self.objtype == 'classmethod':
|
||||
return 'classmethod '
|
||||
return ''
|
||||
|
||||
def get_index_text(self, modname, name_cls):
|
||||
# type: (str, Tuple[str, str]) -> str
|
||||
def get_index_text(self, modname: str, name_cls: Tuple[str, str]) -> str:
|
||||
name, cls = name_cls
|
||||
add_modules = self.env.config.add_module_names
|
||||
if self.objtype == 'method':
|
||||
@ -584,15 +552,13 @@ class PyMethod(PyObject):
|
||||
'staticmethod': directives.flag,
|
||||
})
|
||||
|
||||
def needs_arglist(self):
|
||||
# type: () -> bool
|
||||
def needs_arglist(self) -> bool:
|
||||
if 'property' in self.options:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
def get_signature_prefix(self, sig):
|
||||
# type: (str) -> str
|
||||
def get_signature_prefix(self, sig: str) -> str:
|
||||
prefix = []
|
||||
if 'abstractmethod' in self.options:
|
||||
prefix.append('abstract')
|
||||
@ -610,8 +576,7 @@ class PyMethod(PyObject):
|
||||
else:
|
||||
return ''
|
||||
|
||||
def get_index_text(self, modname, name_cls):
|
||||
# type: (str, Tuple[str, str]) -> str
|
||||
def get_index_text(self, modname: str, name_cls: Tuple[str, str]) -> str:
|
||||
name, cls = name_cls
|
||||
try:
|
||||
clsname, methname = name.rsplit('.', 1)
|
||||
@ -638,8 +603,7 @@ class PyClassMethod(PyMethod):
|
||||
|
||||
option_spec = PyObject.option_spec.copy()
|
||||
|
||||
def run(self):
|
||||
# type: () -> List[nodes.Node]
|
||||
def run(self) -> List[Node]:
|
||||
self.name = 'py:method'
|
||||
self.options['classmethod'] = True
|
||||
|
||||
@ -651,8 +615,7 @@ class PyStaticMethod(PyMethod):
|
||||
|
||||
option_spec = PyObject.option_spec.copy()
|
||||
|
||||
def run(self):
|
||||
# type: () -> List[nodes.Node]
|
||||
def run(self) -> List[Node]:
|
||||
self.name = 'py:method'
|
||||
self.options['staticmethod'] = True
|
||||
|
||||
@ -662,8 +625,7 @@ class PyStaticMethod(PyMethod):
|
||||
class PyAttribute(PyObject):
|
||||
"""Description of an attribute."""
|
||||
|
||||
def get_index_text(self, modname, name_cls):
|
||||
# type: (str, Tuple[str, str]) -> str
|
||||
def get_index_text(self, modname: str, name_cls: Tuple[str, str]) -> str:
|
||||
name, cls = name_cls
|
||||
try:
|
||||
clsname, attrname = name.rsplit('.', 1)
|
||||
@ -682,14 +644,12 @@ class PyDecoratorMixin:
|
||||
"""
|
||||
Mixin for decorator directives.
|
||||
"""
|
||||
def handle_signature(self, sig, signode):
|
||||
# type: (str, addnodes.desc_signature) -> Tuple[str, str]
|
||||
def handle_signature(self, sig: str, signode: desc_signature) -> Tuple[str, str]:
|
||||
ret = super().handle_signature(sig, signode) # type: ignore
|
||||
signode.insert(0, addnodes.desc_addname('@', '@'))
|
||||
return ret
|
||||
|
||||
def needs_arglist(self):
|
||||
# type: () -> bool
|
||||
def needs_arglist(self) -> bool:
|
||||
return False
|
||||
|
||||
|
||||
@ -697,8 +657,7 @@ class PyDecoratorFunction(PyDecoratorMixin, PyModulelevel):
|
||||
"""
|
||||
Directive to mark functions meant to be used as decorators.
|
||||
"""
|
||||
def run(self):
|
||||
# type: () -> List[nodes.Node]
|
||||
def run(self) -> List[Node]:
|
||||
# a decorator function is a function after all
|
||||
self.name = 'py:function'
|
||||
return super().run()
|
||||
@ -708,8 +667,7 @@ class PyDecoratorMethod(PyDecoratorMixin, PyClassmember):
|
||||
"""
|
||||
Directive to mark methods meant to be used as decorators.
|
||||
"""
|
||||
def run(self):
|
||||
# type: () -> List[nodes.Node]
|
||||
def run(self) -> List[Node]:
|
||||
self.name = 'py:method'
|
||||
return super().run()
|
||||
|
||||
@ -730,14 +688,13 @@ class PyModule(SphinxDirective):
|
||||
'deprecated': directives.flag,
|
||||
}
|
||||
|
||||
def run(self):
|
||||
# type: () -> List[nodes.Node]
|
||||
def run(self) -> List[Node]:
|
||||
domain = cast(PythonDomain, self.env.get_domain('py'))
|
||||
|
||||
modname = self.arguments[0].strip()
|
||||
noindex = 'noindex' in self.options
|
||||
self.env.ref_context['py:module'] = modname
|
||||
ret = [] # type: List[nodes.Node]
|
||||
ret = [] # type: List[Node]
|
||||
if not noindex:
|
||||
# note module to the domain
|
||||
domain.note_module(modname,
|
||||
@ -771,8 +728,7 @@ class PyCurrentModule(SphinxDirective):
|
||||
final_argument_whitespace = False
|
||||
option_spec = {} # type: Dict
|
||||
|
||||
def run(self):
|
||||
# type: () -> List[nodes.Node]
|
||||
def run(self) -> List[Node]:
|
||||
modname = self.arguments[0].strip()
|
||||
if modname == 'None':
|
||||
self.env.ref_context.pop('py:module', None)
|
||||
@ -782,8 +738,8 @@ class PyCurrentModule(SphinxDirective):
|
||||
|
||||
|
||||
class PyXRefRole(XRefRole):
|
||||
def process_link(self, env, refnode, has_explicit_title, title, target):
|
||||
# type: (BuildEnvironment, nodes.Element, bool, str, str) -> Tuple[str, str]
|
||||
def process_link(self, env: BuildEnvironment, refnode: Element,
|
||||
has_explicit_title: bool, title: str, target: str) -> Tuple[str, str]:
|
||||
refnode['py:module'] = env.ref_context.get('py:module')
|
||||
refnode['py:class'] = env.ref_context.get('py:class')
|
||||
if not has_explicit_title:
|
||||
@ -813,8 +769,8 @@ class PythonModuleIndex(Index):
|
||||
localname = _('Python Module Index')
|
||||
shortname = _('modules')
|
||||
|
||||
def generate(self, docnames=None):
|
||||
# type: (Iterable[str]) -> Tuple[List[Tuple[str, List[IndexEntry]]], bool]
|
||||
def generate(self, docnames: Iterable[str] = None
|
||||
) -> Tuple[List[Tuple[str, List[IndexEntry]]], bool]:
|
||||
content = {} # type: Dict[str, List[IndexEntry]]
|
||||
# list of prefixes to ignore
|
||||
ignores = None # type: List[str]
|
||||
@ -928,12 +884,10 @@ class PythonDomain(Domain):
|
||||
]
|
||||
|
||||
@property
|
||||
def objects(self):
|
||||
# type: () -> Dict[str, Tuple[str, str]]
|
||||
def objects(self) -> Dict[str, Tuple[str, str]]:
|
||||
return self.data.setdefault('objects', {}) # fullname -> docname, objtype
|
||||
|
||||
def note_object(self, name, objtype, location=None):
|
||||
# type: (str, str, Any) -> None
|
||||
def note_object(self, name: str, objtype: str, location: Any = None) -> None:
|
||||
"""Note a python object for cross reference.
|
||||
|
||||
.. versionadded:: 2.1
|
||||
@ -946,20 +900,17 @@ class PythonDomain(Domain):
|
||||
self.objects[name] = (self.env.docname, objtype)
|
||||
|
||||
@property
|
||||
def modules(self):
|
||||
# type: () -> Dict[str, Tuple[str, str, str, bool]]
|
||||
def modules(self) -> Dict[str, Tuple[str, str, str, bool]]:
|
||||
return self.data.setdefault('modules', {}) # modname -> docname, synopsis, platform, deprecated # NOQA
|
||||
|
||||
def note_module(self, name, synopsis, platform, deprecated):
|
||||
# type: (str, str, str, bool) -> None
|
||||
def note_module(self, name: str, synopsis: str, platform: str, deprecated: bool) -> None:
|
||||
"""Note a python module for cross reference.
|
||||
|
||||
.. versionadded:: 2.1
|
||||
"""
|
||||
self.modules[name] = (self.env.docname, synopsis, platform, deprecated)
|
||||
|
||||
def clear_doc(self, docname):
|
||||
# type: (str) -> None
|
||||
def clear_doc(self, docname: str) -> None:
|
||||
for fullname, (fn, _l) in list(self.objects.items()):
|
||||
if fn == docname:
|
||||
del self.objects[fullname]
|
||||
@ -967,8 +918,7 @@ class PythonDomain(Domain):
|
||||
if fn == docname:
|
||||
del self.modules[modname]
|
||||
|
||||
def merge_domaindata(self, docnames, otherdata):
|
||||
# type: (List[str], Dict) -> None
|
||||
def merge_domaindata(self, docnames: List[str], otherdata: Dict) -> None:
|
||||
# XXX check duplicates?
|
||||
for fullname, (fn, objtype) in otherdata['objects'].items():
|
||||
if fn in docnames:
|
||||
@ -977,8 +927,8 @@ class PythonDomain(Domain):
|
||||
if data[0] in docnames:
|
||||
self.modules[modname] = data
|
||||
|
||||
def find_obj(self, env, modname, classname, name, type, searchmode=0):
|
||||
# type: (BuildEnvironment, str, str, str, str, int) -> List[Tuple[str, Any]]
|
||||
def find_obj(self, env: BuildEnvironment, modname: str, classname: str,
|
||||
name: str, type: str, searchmode: int = 0) -> List[Tuple[str, Any]]:
|
||||
"""Find a Python object for "name", perhaps using the given module
|
||||
and/or classname. Returns a list of (name, object entry) tuples.
|
||||
"""
|
||||
@ -1040,9 +990,9 @@ class PythonDomain(Domain):
|
||||
matches.append((newname, self.objects[newname]))
|
||||
return matches
|
||||
|
||||
def resolve_xref(self, env, fromdocname, builder,
|
||||
type, target, node, contnode):
|
||||
# type: (BuildEnvironment, str, Builder, str, str, addnodes.pending_xref, nodes.Element) -> nodes.Element # NOQA
|
||||
def resolve_xref(self, env: BuildEnvironment, fromdocname: str, builder: Builder,
|
||||
type: str, target: str, node: pending_xref, contnode: Element
|
||||
) -> Element:
|
||||
modname = node.get('py:module')
|
||||
clsname = node.get('py:class')
|
||||
searchmode = node.hasattr('refspecific') and 1 or 0
|
||||
@ -1061,12 +1011,12 @@ class PythonDomain(Domain):
|
||||
else:
|
||||
return make_refnode(builder, fromdocname, obj[0], name, contnode, name)
|
||||
|
||||
def resolve_any_xref(self, env, fromdocname, builder, target,
|
||||
node, contnode):
|
||||
# type: (BuildEnvironment, str, Builder, str, addnodes.pending_xref, nodes.Element) -> List[Tuple[str, nodes.Element]] # NOQA
|
||||
def resolve_any_xref(self, env: BuildEnvironment, fromdocname: str, builder: Builder,
|
||||
target: str, node: pending_xref, contnode: Element
|
||||
) -> List[Tuple[str, Element]]:
|
||||
modname = node.get('py:module')
|
||||
clsname = node.get('py:class')
|
||||
results = [] # type: List[Tuple[str, nodes.Element]]
|
||||
results = [] # type: List[Tuple[str, Element]]
|
||||
|
||||
# always search in "refspecific" mode with the :any: role
|
||||
matches = self.find_obj(env, modname, clsname, target, None, 1)
|
||||
@ -1081,8 +1031,8 @@ class PythonDomain(Domain):
|
||||
contnode, name)))
|
||||
return results
|
||||
|
||||
def _make_module_refnode(self, builder, fromdocname, name, contnode):
|
||||
# type: (Builder, str, str, nodes.Node) -> nodes.Element
|
||||
def _make_module_refnode(self, builder: Builder, fromdocname: str, name: str,
|
||||
contnode: Node) -> Element:
|
||||
# get additional info for modules
|
||||
docname, synopsis, platform, deprecated = self.modules[name]
|
||||
title = name
|
||||
@ -1095,16 +1045,14 @@ class PythonDomain(Domain):
|
||||
return make_refnode(builder, fromdocname, docname,
|
||||
'module-' + name, contnode, title)
|
||||
|
||||
def get_objects(self):
|
||||
# type: () -> Iterator[Tuple[str, str, str, str, str, int]]
|
||||
def get_objects(self) -> Iterator[Tuple[str, str, str, str, str, int]]:
|
||||
for modname, info in self.modules.items():
|
||||
yield (modname, modname, 'module', info[0], 'module-' + modname, 0)
|
||||
for refname, (docname, type) in self.objects.items():
|
||||
if type != 'module': # modules are already handled
|
||||
yield (refname, refname, type, docname, refname, 1)
|
||||
|
||||
def get_full_qualified_name(self, node):
|
||||
# type: (nodes.Element) -> str
|
||||
def get_full_qualified_name(self, node: Element) -> str:
|
||||
modname = node.get('py:module')
|
||||
clsname = node.get('py:class')
|
||||
target = node.get('reftarget')
|
||||
@ -1114,8 +1062,7 @@ class PythonDomain(Domain):
|
||||
return '.'.join(filter(None, [modname, clsname, target]))
|
||||
|
||||
|
||||
def setup(app):
|
||||
# type: (Sphinx) -> Dict[str, Any]
|
||||
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||
app.add_domain(PythonDomain)
|
||||
|
||||
return {
|
||||
|
@ -9,26 +9,24 @@
|
||||
"""
|
||||
|
||||
import re
|
||||
from typing import Any, Dict, Iterator, List, Tuple
|
||||
from typing import cast
|
||||
|
||||
from docutils.nodes import Element
|
||||
from docutils.parsers.rst import directives
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx.addnodes import desc_signature, pending_xref
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.builders import Builder
|
||||
from sphinx.directives import ObjectDescription
|
||||
from sphinx.domains import Domain, ObjType
|
||||
from sphinx.environment import BuildEnvironment
|
||||
from sphinx.locale import _, __
|
||||
from sphinx.roles import XRefRole
|
||||
from sphinx.util import logging
|
||||
from sphinx.util.nodes import make_refnode
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Any, Dict, Iterator, List, Tuple # NOQA
|
||||
from docutils import nodes # NOQA
|
||||
from sphinx.application import Sphinx # NOQA
|
||||
from sphinx.builders import Builder # NOQA
|
||||
from sphinx.environment import BuildEnvironment # NOQA
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -40,8 +38,7 @@ class ReSTMarkup(ObjectDescription):
|
||||
Description of generic reST markup.
|
||||
"""
|
||||
|
||||
def add_target_and_index(self, name, sig, signode):
|
||||
# type: (str, str, addnodes.desc_signature) -> None
|
||||
def add_target_and_index(self, name: str, sig: str, signode: desc_signature) -> None:
|
||||
targetname = self.objtype + '-' + name
|
||||
if targetname not in self.state.document.ids:
|
||||
signode['names'].append(targetname)
|
||||
@ -57,13 +54,11 @@ class ReSTMarkup(ObjectDescription):
|
||||
self.indexnode['entries'].append(('single', indextext,
|
||||
targetname, '', None))
|
||||
|
||||
def get_index_text(self, objectname, name):
|
||||
# type: (str, str) -> str
|
||||
def get_index_text(self, objectname: str, name: str) -> str:
|
||||
return ''
|
||||
|
||||
|
||||
def parse_directive(d):
|
||||
# type: (str) -> Tuple[str, str]
|
||||
def parse_directive(d: str) -> Tuple[str, str]:
|
||||
"""Parse a directive signature.
|
||||
|
||||
Returns (directive, arguments) string tuple. If no arguments are given,
|
||||
@ -87,8 +82,7 @@ class ReSTDirective(ReSTMarkup):
|
||||
"""
|
||||
Description of a reST directive.
|
||||
"""
|
||||
def handle_signature(self, sig, signode):
|
||||
# type: (str, addnodes.desc_signature) -> str
|
||||
def handle_signature(self, sig: str, signode: desc_signature) -> str:
|
||||
name, args = parse_directive(sig)
|
||||
desc_name = '.. %s::' % name
|
||||
signode += addnodes.desc_name(desc_name, desc_name)
|
||||
@ -96,18 +90,15 @@ class ReSTDirective(ReSTMarkup):
|
||||
signode += addnodes.desc_addname(args, args)
|
||||
return name
|
||||
|
||||
def get_index_text(self, objectname, name):
|
||||
# type: (str, str) -> str
|
||||
def get_index_text(self, objectname: str, name: str) -> str:
|
||||
return _('%s (directive)') % name
|
||||
|
||||
def before_content(self):
|
||||
# type: () -> None
|
||||
def before_content(self) -> None:
|
||||
if self.names:
|
||||
directives = self.env.ref_context.setdefault('rst:directives', [])
|
||||
directives.append(self.names[0])
|
||||
|
||||
def after_content(self):
|
||||
# type: () -> None
|
||||
def after_content(self) -> None:
|
||||
directives = self.env.ref_context.setdefault('rst:directives', [])
|
||||
if directives:
|
||||
directives.pop()
|
||||
@ -122,8 +113,7 @@ class ReSTDirectiveOption(ReSTMarkup):
|
||||
'type': directives.unchanged,
|
||||
})
|
||||
|
||||
def handle_signature(self, sig, signode):
|
||||
# type: (str, addnodes.desc_signature) -> str
|
||||
def handle_signature(self, sig: str, signode: desc_signature) -> str:
|
||||
try:
|
||||
name, argument = re.split(r'\s*:\s+', sig.strip(), 1)
|
||||
except ValueError:
|
||||
@ -137,8 +127,7 @@ class ReSTDirectiveOption(ReSTMarkup):
|
||||
signode += addnodes.desc_annotation(text, text)
|
||||
return name
|
||||
|
||||
def add_target_and_index(self, name, sig, signode):
|
||||
# type: (str, str, addnodes.desc_signature) -> None
|
||||
def add_target_and_index(self, name: str, sig: str, signode: desc_signature) -> None:
|
||||
directive_name = self.current_directive
|
||||
targetname = '-'.join([self.objtype, self.current_directive, name])
|
||||
if targetname not in self.state.document.ids:
|
||||
@ -162,8 +151,7 @@ class ReSTDirectiveOption(ReSTMarkup):
|
||||
self.indexnode['entries'].append(('single', text, targetname, '', key))
|
||||
|
||||
@property
|
||||
def current_directive(self):
|
||||
# type: () -> str
|
||||
def current_directive(self) -> str:
|
||||
directives = self.env.ref_context.get('rst:directives')
|
||||
if directives:
|
||||
return directives[-1]
|
||||
@ -175,13 +163,11 @@ class ReSTRole(ReSTMarkup):
|
||||
"""
|
||||
Description of a reST role.
|
||||
"""
|
||||
def handle_signature(self, sig, signode):
|
||||
# type: (str, addnodes.desc_signature) -> str
|
||||
def handle_signature(self, sig: str, signode: desc_signature) -> str:
|
||||
signode += addnodes.desc_name(':%s:' % sig, ':%s:' % sig)
|
||||
return sig
|
||||
|
||||
def get_index_text(self, objectname, name):
|
||||
# type: (str, str) -> str
|
||||
def get_index_text(self, objectname: str, name: str) -> str:
|
||||
return _('%s (role)') % name
|
||||
|
||||
|
||||
@ -209,12 +195,10 @@ class ReSTDomain(Domain):
|
||||
} # type: Dict[str, Dict[Tuple[str, str], str]]
|
||||
|
||||
@property
|
||||
def objects(self):
|
||||
# type: () -> Dict[Tuple[str, str], str]
|
||||
def objects(self) -> Dict[Tuple[str, str], str]:
|
||||
return self.data.setdefault('objects', {}) # (objtype, fullname) -> docname
|
||||
|
||||
def note_object(self, objtype, name, location=None):
|
||||
# type: (str, str, Any) -> None
|
||||
def note_object(self, objtype: str, name: str, location: Any = None) -> None:
|
||||
if (objtype, name) in self.objects:
|
||||
docname = self.objects[objtype, name]
|
||||
logger.warning(__('duplicate description of %s %s, other instance in %s') %
|
||||
@ -222,21 +206,20 @@ class ReSTDomain(Domain):
|
||||
|
||||
self.objects[objtype, name] = self.env.docname
|
||||
|
||||
def clear_doc(self, docname):
|
||||
# type: (str) -> None
|
||||
def clear_doc(self, docname: str) -> None:
|
||||
for (typ, name), doc in list(self.objects.items()):
|
||||
if doc == docname:
|
||||
del self.objects[typ, name]
|
||||
|
||||
def merge_domaindata(self, docnames, otherdata):
|
||||
# type: (List[str], Dict) -> None
|
||||
def merge_domaindata(self, docnames: List[str], otherdata: Dict) -> None:
|
||||
# XXX check duplicates
|
||||
for (typ, name), doc in otherdata['objects'].items():
|
||||
if doc in docnames:
|
||||
self.objects[typ, name] = doc
|
||||
|
||||
def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode):
|
||||
# type: (BuildEnvironment, str, Builder, str, str, addnodes.pending_xref, nodes.Element) -> nodes.Element # NOQA
|
||||
def resolve_xref(self, env: BuildEnvironment, fromdocname: str, builder: Builder,
|
||||
typ: str, target: str, node: pending_xref, contnode: Element
|
||||
) -> Element:
|
||||
objtypes = self.objtypes_for_role(typ)
|
||||
for objtype in objtypes:
|
||||
todocname = self.objects.get((objtype, target))
|
||||
@ -246,9 +229,10 @@ class ReSTDomain(Domain):
|
||||
contnode, target + ' ' + objtype)
|
||||
return None
|
||||
|
||||
def resolve_any_xref(self, env, fromdocname, builder, target, node, contnode):
|
||||
# type: (BuildEnvironment, str, Builder, str, addnodes.pending_xref, nodes.Element) -> List[Tuple[str, nodes.Element]] # NOQA
|
||||
results = [] # type: List[Tuple[str, nodes.Element]]
|
||||
def resolve_any_xref(self, env: BuildEnvironment, fromdocname: str, builder: Builder,
|
||||
target: str, node: pending_xref, contnode: Element
|
||||
) -> List[Tuple[str, Element]]:
|
||||
results = [] # type: List[Tuple[str, Element]]
|
||||
for objtype in self.object_types:
|
||||
todocname = self.objects.get((objtype, target))
|
||||
if todocname:
|
||||
@ -258,14 +242,12 @@ class ReSTDomain(Domain):
|
||||
contnode, target + ' ' + objtype)))
|
||||
return results
|
||||
|
||||
def get_objects(self):
|
||||
# type: () -> Iterator[Tuple[str, str, str, str, str, int]]
|
||||
def get_objects(self) -> Iterator[Tuple[str, str, str, str, str, int]]:
|
||||
for (typ, name), docname in self.data['objects'].items():
|
||||
yield name, name, typ, docname, typ + '-' + name, 1
|
||||
|
||||
|
||||
def setup(app):
|
||||
# type: (Sphinx) -> Dict[str, Any]
|
||||
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||
app.add_domain(ReSTDomain)
|
||||
|
||||
return {
|
||||
|
@ -12,13 +12,16 @@ import re
|
||||
import unicodedata
|
||||
import warnings
|
||||
from copy import copy
|
||||
from typing import Any, Callable, Dict, Iterable, Iterator, List, Optional, Tuple, Type, Union
|
||||
from typing import cast
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.parsers.rst import directives
|
||||
from docutils.nodes import Element, Node, system_message
|
||||
from docutils.parsers.rst import Directive, directives
|
||||
from docutils.statemachine import StringList
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx.addnodes import desc_signature, pending_xref
|
||||
from sphinx.deprecation import RemovedInSphinx40Warning
|
||||
from sphinx.directives import ObjectDescription
|
||||
from sphinx.domains import Domain, ObjType
|
||||
@ -27,15 +30,13 @@ from sphinx.roles import XRefRole
|
||||
from sphinx.util import ws_re, logging, docname_join
|
||||
from sphinx.util.docutils import SphinxDirective
|
||||
from sphinx.util.nodes import clean_astext, make_refnode
|
||||
from sphinx.util.typing import RoleFunction
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Any, Callable, Dict, Iterable, Iterator, List, Tuple, Type, Union # NOQA
|
||||
from docutils.parsers.rst import Directive # NOQA
|
||||
from sphinx.application import Sphinx # NOQA
|
||||
from sphinx.builders import Builder # NOQA
|
||||
from sphinx.environment import BuildEnvironment # NOQA
|
||||
from sphinx.util.typing import RoleFunction # NOQA
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.builders import Builder
|
||||
from sphinx.environment import BuildEnvironment
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -51,10 +52,9 @@ class GenericObject(ObjectDescription):
|
||||
A generic x-ref directive registered with Sphinx.add_object_type().
|
||||
"""
|
||||
indextemplate = ''
|
||||
parse_node = None # type: Callable[[GenericObject, BuildEnvironment, str, addnodes.desc_signature], str] # NOQA
|
||||
parse_node = None # type: Callable[[GenericObject, BuildEnvironment, str, desc_signature], str] # NOQA
|
||||
|
||||
def handle_signature(self, sig, signode):
|
||||
# type: (str, addnodes.desc_signature) -> str
|
||||
def handle_signature(self, sig: str, signode: desc_signature) -> str:
|
||||
if self.parse_node:
|
||||
name = self.parse_node(self.env, sig, signode)
|
||||
else:
|
||||
@ -64,8 +64,7 @@ class GenericObject(ObjectDescription):
|
||||
name = ws_re.sub('', sig)
|
||||
return name
|
||||
|
||||
def add_target_and_index(self, name, sig, signode):
|
||||
# type: (str, str, addnodes.desc_signature) -> None
|
||||
def add_target_and_index(self, name: str, sig: str, signode: desc_signature) -> None:
|
||||
targetname = '%s-%s' % (self.objtype, name)
|
||||
signode['ids'].append(targetname)
|
||||
self.state.document.note_explicit_target(signode)
|
||||
@ -93,8 +92,8 @@ class EnvVarXRefRole(XRefRole):
|
||||
Cross-referencing role for environment variables (adds an index entry).
|
||||
"""
|
||||
|
||||
def result_nodes(self, document, env, node, is_ref):
|
||||
# type: (nodes.document, BuildEnvironment, nodes.Element, bool) -> Tuple[List[nodes.Node], List[nodes.system_message]] # NOQA
|
||||
def result_nodes(self, document: nodes.document, env: "BuildEnvironment", node: Element,
|
||||
is_ref: bool) -> Tuple[List[Node], List[system_message]]:
|
||||
if not is_ref:
|
||||
return [node], []
|
||||
varname = node['reftarget']
|
||||
@ -121,8 +120,7 @@ class Target(SphinxDirective):
|
||||
final_argument_whitespace = True
|
||||
option_spec = {} # type: Dict
|
||||
|
||||
def run(self):
|
||||
# type: () -> List[nodes.Node]
|
||||
def run(self) -> List[Node]:
|
||||
# normalize whitespace in fullname like XRefRole does
|
||||
fullname = ws_re.sub(' ', self.arguments[0].strip())
|
||||
targetname = '%s-%s' % (self.name, fullname)
|
||||
@ -154,8 +152,7 @@ class Cmdoption(ObjectDescription):
|
||||
Description of a command-line option (.. option).
|
||||
"""
|
||||
|
||||
def handle_signature(self, sig, signode):
|
||||
# type: (str, addnodes.desc_signature) -> str
|
||||
def handle_signature(self, sig: str, signode: desc_signature) -> str:
|
||||
"""Transform an option description into RST nodes."""
|
||||
count = 0
|
||||
firstname = ''
|
||||
@ -183,8 +180,7 @@ class Cmdoption(ObjectDescription):
|
||||
raise ValueError
|
||||
return firstname
|
||||
|
||||
def add_target_and_index(self, firstname, sig, signode):
|
||||
# type: (str, str, addnodes.desc_signature) -> None
|
||||
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', []):
|
||||
targetname = optname.replace('/', '-')
|
||||
@ -220,8 +216,7 @@ class Program(SphinxDirective):
|
||||
final_argument_whitespace = True
|
||||
option_spec = {} # type: Dict
|
||||
|
||||
def run(self):
|
||||
# type: () -> List[nodes.Node]
|
||||
def run(self) -> List[Node]:
|
||||
program = ws_re.sub('-', self.arguments[0].strip())
|
||||
if program == 'None':
|
||||
self.env.ref_context.pop('std:program', None)
|
||||
@ -231,21 +226,20 @@ class Program(SphinxDirective):
|
||||
|
||||
|
||||
class OptionXRefRole(XRefRole):
|
||||
def process_link(self, env, refnode, has_explicit_title, title, target):
|
||||
# type: (BuildEnvironment, nodes.Element, bool, str, str) -> Tuple[str, str]
|
||||
def process_link(self, env: "BuildEnvironment", refnode: Element, has_explicit_title: bool,
|
||||
title: str, target: str) -> Tuple[str, str]:
|
||||
refnode['std:program'] = env.ref_context.get('std:program')
|
||||
return title, target
|
||||
|
||||
|
||||
def split_term_classifiers(line):
|
||||
# type: (str) -> List[Union[str, None]]
|
||||
def split_term_classifiers(line: str) -> List[Optional[str]]:
|
||||
# split line into a term and classifiers. if no classifier, None is used..
|
||||
parts = re.split(' +: +', line) + [None]
|
||||
return parts
|
||||
|
||||
|
||||
def make_glossary_term(env, textnodes, index_key, source, lineno, new_id=None):
|
||||
# type: (BuildEnvironment, Iterable[nodes.Node], str, str, int, str) -> nodes.term
|
||||
def make_glossary_term(env: "BuildEnvironment", textnodes: Iterable[Node], index_key: str,
|
||||
source: str, lineno: int, new_id: str = None) -> nodes.term:
|
||||
# get a text-only representation of the term and register it
|
||||
# as a cross-reference target
|
||||
term = nodes.term('', '', *textnodes)
|
||||
@ -291,8 +285,7 @@ class Glossary(SphinxDirective):
|
||||
'sorted': directives.flag,
|
||||
}
|
||||
|
||||
def run(self):
|
||||
# type: () -> List[nodes.Node]
|
||||
def run(self) -> List[Node]:
|
||||
node = addnodes.glossary()
|
||||
node.document = self.state.document
|
||||
|
||||
@ -398,16 +391,15 @@ class Glossary(SphinxDirective):
|
||||
return messages + [node]
|
||||
|
||||
|
||||
def token_xrefs(text):
|
||||
# type: (str) -> List[nodes.Node]
|
||||
def token_xrefs(text: str) -> List[Node]:
|
||||
retnodes = [] # type: List[nodes.Node]
|
||||
pos = 0
|
||||
for m in token_re.finditer(text):
|
||||
if m.start() > pos:
|
||||
txt = text[pos:m.start()]
|
||||
retnodes.append(nodes.Text(txt, txt))
|
||||
refnode = addnodes.pending_xref(
|
||||
m.group(1), reftype='token', refdomain='std', reftarget=m.group(1))
|
||||
refnode = pending_xref(m.group(1), reftype='token', refdomain='std',
|
||||
reftarget=m.group(1))
|
||||
refnode += nodes.literal(m.group(1), m.group(1), classes=['xref'])
|
||||
retnodes.append(refnode)
|
||||
pos = m.end()
|
||||
@ -427,8 +419,7 @@ class ProductionList(SphinxDirective):
|
||||
final_argument_whitespace = True
|
||||
option_spec = {} # type: Dict
|
||||
|
||||
def run(self):
|
||||
# type: () -> List[nodes.Node]
|
||||
def run(self) -> List[Node]:
|
||||
domain = cast(StandardDomain, self.env.get_domain('std'))
|
||||
node = addnodes.productionlist() # type: nodes.Element
|
||||
i = 0
|
||||
@ -533,8 +524,7 @@ class StandardDomain(Domain):
|
||||
nodes.container: ('code-block', None),
|
||||
} # type: Dict[Type[nodes.Node], Tuple[str, Callable]]
|
||||
|
||||
def __init__(self, env):
|
||||
# type: (BuildEnvironment) -> None
|
||||
def __init__(self, env: "BuildEnvironment") -> None:
|
||||
super().__init__(env)
|
||||
|
||||
# set up enumerable nodes
|
||||
@ -543,27 +533,22 @@ class StandardDomain(Domain):
|
||||
self.enumerable_nodes[node] = settings
|
||||
|
||||
@property
|
||||
def objects(self):
|
||||
# type: () -> Dict[Tuple[str, str], Tuple[str, str]]
|
||||
def objects(self) -> Dict[Tuple[str, str], Tuple[str, str]]:
|
||||
return self.data.setdefault('objects', {}) # (objtype, name) -> docname, labelid
|
||||
|
||||
@property
|
||||
def progoptions(self):
|
||||
# type: () -> Dict[Tuple[str, str], Tuple[str, str]]
|
||||
def progoptions(self) -> Dict[Tuple[str, str], Tuple[str, str]]:
|
||||
return self.data.setdefault('progoptions', {}) # (program, name) -> docname, labelid
|
||||
|
||||
@property
|
||||
def labels(self):
|
||||
# type: () -> Dict[str, Tuple[str, str, str]]
|
||||
def labels(self) -> Dict[str, Tuple[str, str, str]]:
|
||||
return self.data.setdefault('labels', {}) # labelname -> docname, labelid, sectionname
|
||||
|
||||
@property
|
||||
def anonlabels(self):
|
||||
# type: () -> Dict[str, Tuple[str, str]]
|
||||
def anonlabels(self) -> Dict[str, Tuple[str, str]]:
|
||||
return self.data.setdefault('anonlabels', {}) # labelname -> docname, labelid
|
||||
|
||||
def clear_doc(self, docname):
|
||||
# type: (str) -> None
|
||||
def clear_doc(self, docname: str) -> None:
|
||||
key = None # type: Any
|
||||
for key, (fn, _l) in list(self.progoptions.items()):
|
||||
if fn == docname:
|
||||
@ -578,8 +563,7 @@ class StandardDomain(Domain):
|
||||
if fn == docname:
|
||||
del self.anonlabels[key]
|
||||
|
||||
def merge_domaindata(self, docnames, otherdata):
|
||||
# type: (List[str], Dict) -> None
|
||||
def merge_domaindata(self, docnames: List[str], otherdata: Dict) -> None:
|
||||
# XXX duplicates?
|
||||
for key, data in otherdata['progoptions'].items():
|
||||
if data[0] in docnames:
|
||||
@ -594,8 +578,7 @@ class StandardDomain(Domain):
|
||||
if data[0] in docnames:
|
||||
self.anonlabels[key] = data
|
||||
|
||||
def process_doc(self, env, docname, document):
|
||||
# type: (BuildEnvironment, str, nodes.document) -> None
|
||||
def process_doc(self, env: "BuildEnvironment", docname: str, document: nodes.document) -> None: # NOQA
|
||||
for name, explicit in document.nametypes.items():
|
||||
if not explicit:
|
||||
continue
|
||||
@ -636,17 +619,15 @@ class StandardDomain(Domain):
|
||||
continue
|
||||
self.labels[name] = docname, labelid, sectname
|
||||
|
||||
def add_object(self, objtype, name, docname, labelid):
|
||||
# type: (str, str, str, str) -> None
|
||||
def add_object(self, objtype: str, name: str, docname: str, labelid: str) -> None:
|
||||
self.objects[objtype, name] = (docname, labelid)
|
||||
|
||||
def add_program_option(self, program, name, docname, labelid):
|
||||
# type: (str, str, str, str) -> None
|
||||
def add_program_option(self, program: str, name: str, docname: str, labelid: str) -> None:
|
||||
self.progoptions[program, name] = (docname, labelid)
|
||||
|
||||
def build_reference_node(self, fromdocname, builder, docname, labelid,
|
||||
sectname, rolename, **options):
|
||||
# type: (str, Builder, str, str, str, str, Any) -> nodes.Element
|
||||
def build_reference_node(self, fromdocname: str, builder: "Builder", docname: str,
|
||||
labelid: str, sectname: str, rolename: str, **options
|
||||
) -> Element:
|
||||
nodeclass = options.pop('nodeclass', nodes.reference)
|
||||
newnode = nodeclass('', '', internal=True, **options)
|
||||
innernode = nodes.inline(sectname, sectname)
|
||||
@ -659,7 +640,7 @@ class StandardDomain(Domain):
|
||||
# set more info in contnode; in case the
|
||||
# get_relative_uri call raises NoUri,
|
||||
# the builder will then have to resolve these
|
||||
contnode = addnodes.pending_xref('')
|
||||
contnode = pending_xref('')
|
||||
contnode['refdocname'] = docname
|
||||
contnode['refsectname'] = sectname
|
||||
newnode['refuri'] = builder.get_relative_uri(
|
||||
@ -669,8 +650,8 @@ class StandardDomain(Domain):
|
||||
newnode.append(innernode)
|
||||
return newnode
|
||||
|
||||
def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode):
|
||||
# type: (BuildEnvironment, str, Builder, str, str, addnodes.pending_xref, nodes.Element) -> nodes.Element # NOQA
|
||||
def resolve_xref(self, env: "BuildEnvironment", fromdocname: str, builder: "Builder",
|
||||
typ: str, target: str, node: pending_xref, contnode: Element) -> Element:
|
||||
if typ == 'ref':
|
||||
resolver = self._resolve_ref_xref
|
||||
elif typ == 'numref':
|
||||
@ -691,8 +672,9 @@ class StandardDomain(Domain):
|
||||
|
||||
return resolver(env, fromdocname, builder, typ, target, node, contnode)
|
||||
|
||||
def _resolve_ref_xref(self, env, fromdocname, builder, typ, target, node, contnode):
|
||||
# type: (BuildEnvironment, str, Builder, str, str, addnodes.pending_xref, nodes.Element) -> nodes.Element # NOQA
|
||||
def _resolve_ref_xref(self, env: "BuildEnvironment", fromdocname: str,
|
||||
builder: "Builder", typ: str, target: str, node: pending_xref,
|
||||
contnode: Element) -> Element:
|
||||
if node['refexplicit']:
|
||||
# reference to anonymous label; the reference uses
|
||||
# the supplied link caption
|
||||
@ -708,8 +690,9 @@ class StandardDomain(Domain):
|
||||
return self.build_reference_node(fromdocname, builder,
|
||||
docname, labelid, sectname, 'ref')
|
||||
|
||||
def _resolve_numref_xref(self, env, fromdocname, builder, typ, target, node, contnode):
|
||||
# type: (BuildEnvironment, str, Builder, str, str, addnodes.pending_xref, nodes.Element) -> nodes.Element # NOQA
|
||||
def _resolve_numref_xref(self, env: "BuildEnvironment", fromdocname: str,
|
||||
builder: "Builder", typ: str, target: str,
|
||||
node: pending_xref, contnode: Element) -> Element:
|
||||
if target in self.labels:
|
||||
docname, labelid, figname = self.labels.get(target, ('', '', ''))
|
||||
else:
|
||||
@ -769,8 +752,9 @@ class StandardDomain(Domain):
|
||||
nodeclass=addnodes.number_reference,
|
||||
title=title)
|
||||
|
||||
def _resolve_keyword_xref(self, env, fromdocname, builder, typ, target, node, contnode):
|
||||
# type: (BuildEnvironment, str, Builder, str, str, addnodes.pending_xref, nodes.Element) -> nodes.Element # NOQA
|
||||
def _resolve_keyword_xref(self, env: "BuildEnvironment", fromdocname: str,
|
||||
builder: "Builder", typ: str, target: str,
|
||||
node: pending_xref, contnode: Element) -> Element:
|
||||
# keywords are oddballs: they are referenced by named labels
|
||||
docname, labelid, _ = self.labels.get(target, ('', '', ''))
|
||||
if not docname:
|
||||
@ -778,8 +762,9 @@ class StandardDomain(Domain):
|
||||
return make_refnode(builder, fromdocname, docname,
|
||||
labelid, contnode)
|
||||
|
||||
def _resolve_doc_xref(self, env, fromdocname, builder, typ, target, node, contnode):
|
||||
# type: (BuildEnvironment, str, Builder, str, str, addnodes.pending_xref, nodes.Element) -> nodes.Element # NOQA
|
||||
def _resolve_doc_xref(self, env: "BuildEnvironment", fromdocname: str,
|
||||
builder: "Builder", typ: str, target: str,
|
||||
node: pending_xref, contnode: Element) -> Element:
|
||||
# directly reference to document by source name; can be absolute or relative
|
||||
refdoc = node.get('refdoc', fromdocname)
|
||||
docname = docname_join(refdoc, node['reftarget'])
|
||||
@ -794,8 +779,9 @@ class StandardDomain(Domain):
|
||||
innernode = nodes.inline(caption, caption, classes=['doc'])
|
||||
return make_refnode(builder, fromdocname, docname, None, innernode)
|
||||
|
||||
def _resolve_option_xref(self, env, fromdocname, builder, typ, target, node, contnode):
|
||||
# type: (BuildEnvironment, str, Builder, str, str, addnodes.pending_xref, nodes.Element) -> nodes.Element # NOQA
|
||||
def _resolve_option_xref(self, env: "BuildEnvironment", fromdocname: str,
|
||||
builder: "Builder", typ: str, target: str,
|
||||
node: pending_xref, contnode: Element) -> Element:
|
||||
progname = node.get('std:program')
|
||||
target = target.strip()
|
||||
docname, labelid = self.progoptions.get((progname, target), ('', ''))
|
||||
@ -815,8 +801,9 @@ class StandardDomain(Domain):
|
||||
return make_refnode(builder, fromdocname, docname,
|
||||
labelid, contnode)
|
||||
|
||||
def _resolve_obj_xref(self, env, fromdocname, builder, typ, target, node, contnode):
|
||||
# type: (BuildEnvironment, str, Builder, str, str, addnodes.pending_xref, nodes.Element) -> nodes.Element # NOQA
|
||||
def _resolve_obj_xref(self, env: "BuildEnvironment", fromdocname: str,
|
||||
builder: "Builder", typ: str, target: str,
|
||||
node: pending_xref, contnode: Element) -> Element:
|
||||
objtypes = self.objtypes_for_role(typ) or []
|
||||
for objtype in objtypes:
|
||||
if (objtype, target) in self.objects:
|
||||
@ -829,8 +816,9 @@ class StandardDomain(Domain):
|
||||
return make_refnode(builder, fromdocname, docname,
|
||||
labelid, contnode)
|
||||
|
||||
def resolve_any_xref(self, env, fromdocname, builder, target, node, contnode):
|
||||
# type: (BuildEnvironment, str, Builder, str, addnodes.pending_xref, nodes.Element) -> List[Tuple[str, nodes.Element]] # NOQA
|
||||
def resolve_any_xref(self, env: "BuildEnvironment", fromdocname: str,
|
||||
builder: "Builder", target: str, node: pending_xref,
|
||||
contnode: Element) -> List[Tuple[str, Element]]:
|
||||
results = [] # type: List[Tuple[str, nodes.Element]]
|
||||
ltarget = target.lower() # :ref: lowercases its target automatically
|
||||
for role in ('ref', 'option'): # do not try "keyword"
|
||||
@ -851,8 +839,7 @@ class StandardDomain(Domain):
|
||||
labelid, contnode)))
|
||||
return results
|
||||
|
||||
def get_objects(self):
|
||||
# type: () -> Iterator[Tuple[str, str, str, str, str, int]]
|
||||
def get_objects(self) -> Iterator[Tuple[str, str, str, str, str, int]]:
|
||||
# handle the special 'doc' reference here
|
||||
for doc in self.env.all_docs:
|
||||
yield (doc, clean_astext(self.env.titles[doc]), 'doc', doc, '', -1)
|
||||
@ -873,17 +860,14 @@ class StandardDomain(Domain):
|
||||
if name not in non_anon_labels:
|
||||
yield (name, name, 'label', docname, labelid, -1)
|
||||
|
||||
def get_type_name(self, type, primary=False):
|
||||
# type: (ObjType, bool) -> str
|
||||
def get_type_name(self, type: ObjType, primary: bool = False) -> str:
|
||||
# never prepend "Default"
|
||||
return type.lname
|
||||
|
||||
def is_enumerable_node(self, node):
|
||||
# type: (nodes.Node) -> bool
|
||||
def is_enumerable_node(self, node: Node) -> bool:
|
||||
return node.__class__ in self.enumerable_nodes
|
||||
|
||||
def get_numfig_title(self, node):
|
||||
# type: (nodes.Node) -> str
|
||||
def get_numfig_title(self, node: Node) -> str:
|
||||
"""Get the title of enumerable nodes to refer them using its title"""
|
||||
if self.is_enumerable_node(node):
|
||||
elem = cast(nodes.Element, node)
|
||||
@ -897,11 +881,9 @@ class StandardDomain(Domain):
|
||||
|
||||
return None
|
||||
|
||||
def get_enumerable_node_type(self, node):
|
||||
# type: (nodes.Node) -> str
|
||||
def get_enumerable_node_type(self, node: Node) -> str:
|
||||
"""Get type of enumerable nodes."""
|
||||
def has_child(node, cls):
|
||||
# type: (nodes.Element, Type) -> bool
|
||||
def has_child(node: Element, cls: Type) -> bool:
|
||||
return any(isinstance(child, cls) for child in node)
|
||||
|
||||
if isinstance(node, nodes.section):
|
||||
@ -915,8 +897,8 @@ class StandardDomain(Domain):
|
||||
figtype, _ = self.enumerable_nodes.get(node.__class__, (None, None))
|
||||
return figtype
|
||||
|
||||
def get_fignumber(self, env, builder, figtype, docname, target_node):
|
||||
# type: (BuildEnvironment, Builder, str, str, nodes.Element) -> Tuple[int, ...]
|
||||
def get_fignumber(self, env: "BuildEnvironment", builder: "Builder",
|
||||
figtype: str, docname: str, target_node: Element) -> Tuple[int, ...]:
|
||||
if figtype == 'section':
|
||||
if builder.name == 'latex':
|
||||
return tuple()
|
||||
@ -938,8 +920,7 @@ class StandardDomain(Domain):
|
||||
# Maybe it is defined in orphaned document.
|
||||
raise ValueError
|
||||
|
||||
def get_full_qualified_name(self, node):
|
||||
# type: (nodes.Element) -> str
|
||||
def get_full_qualified_name(self, node: Element) -> str:
|
||||
if node.get('reftype') == 'option':
|
||||
progname = node.get('std:program')
|
||||
command = ws_re.split(node.get('reftarget'))
|
||||
@ -953,24 +934,20 @@ class StandardDomain(Domain):
|
||||
else:
|
||||
return None
|
||||
|
||||
def note_citations(self, env, docname, document):
|
||||
# type: (BuildEnvironment, str, nodes.document) -> None
|
||||
def note_citations(self, env: "BuildEnvironment", docname: str, document: nodes.document) -> None: # NOQA
|
||||
warnings.warn('StandardDomain.note_citations() is deprecated.',
|
||||
RemovedInSphinx40Warning)
|
||||
|
||||
def note_citation_refs(self, env, docname, document):
|
||||
# type: (BuildEnvironment, str, nodes.document) -> None
|
||||
def note_citation_refs(self, env: "BuildEnvironment", docname: str, document: nodes.document) -> None: # NOQA
|
||||
warnings.warn('StandardDomain.note_citation_refs() is deprecated.',
|
||||
RemovedInSphinx40Warning)
|
||||
|
||||
def note_labels(self, env, docname, document):
|
||||
# type: (BuildEnvironment, str, nodes.document) -> None
|
||||
def note_labels(self, env: "BuildEnvironment", docname: str, document: nodes.document) -> None: # NOQA
|
||||
warnings.warn('StandardDomain.note_labels() is deprecated.',
|
||||
RemovedInSphinx40Warning)
|
||||
|
||||
|
||||
def setup(app):
|
||||
# type: (Sphinx) -> Dict[str, Any]
|
||||
def setup(app: "Sphinx") -> Dict[str, Any]:
|
||||
app.add_domain(StandardDomain)
|
||||
|
||||
return {
|
||||
|
@ -270,7 +270,7 @@ def format_date(format: str, date: datetime = None, language: str = None) -> str
|
||||
if source_date_epoch is not None:
|
||||
date = datetime.utcfromtimestamp(float(source_date_epoch))
|
||||
else:
|
||||
date = datetime.now()
|
||||
date = datetime.utcnow()
|
||||
|
||||
result = []
|
||||
tokens = date_format_re.split(format)
|
||||
|
Loading…
Reference in New Issue
Block a user