refactor: Add a type alias for the option_spec of directives; OptionSpec

This commit is contained in:
Takeshi KOMIYA 2021-03-13 17:10:50 +09:00
parent c817c20626
commit a523a89663
22 changed files with 107 additions and 71 deletions

View File

@ -57,6 +57,7 @@ Deprecated
* ``sphinx.util.pycompat.convert_with_2to3()`` * ``sphinx.util.pycompat.convert_with_2to3()``
* ``sphinx.util.pycompat.execfile_()`` * ``sphinx.util.pycompat.execfile_()``
* ``sphinx.util.smartypants`` * ``sphinx.util.smartypants``
* ``sphinx.util.typing.DirectiveOption``
Features added Features added
-------------- --------------

View File

@ -72,6 +72,11 @@ The following is a list of deprecated interfaces.
- 6.0 - 6.0
- ``docutils.utils.smartyquotes`` - ``docutils.utils.smartyquotes``
* - ``sphinx.util.typing.DirectiveOption``
- 4.0
- 6.0
- N/A
* - pending_xref node for viewcode extension * - pending_xref node for viewcode extension
- 3.5 - 3.5
- 5.0 - 5.0

View File

@ -21,7 +21,7 @@ from sphinx.deprecation import RemovedInSphinx50Warning, deprecated_alias
from sphinx.util import docutils from sphinx.util import docutils
from sphinx.util.docfields import DocFieldTransformer, Field, TypedField from sphinx.util.docfields import DocFieldTransformer, Field, TypedField
from sphinx.util.docutils import SphinxDirective from sphinx.util.docutils import SphinxDirective
from sphinx.util.typing import DirectiveOption from sphinx.util.typing import OptionSpec
if TYPE_CHECKING: if TYPE_CHECKING:
from sphinx.application import Sphinx from sphinx.application import Sphinx
@ -58,9 +58,9 @@ class ObjectDescription(SphinxDirective, Generic[T]):
required_arguments = 1 required_arguments = 1
optional_arguments = 0 optional_arguments = 0
final_argument_whitespace = True final_argument_whitespace = True
option_spec = { option_spec: OptionSpec = {
'noindex': directives.flag, 'noindex': directives.flag,
} # type: Dict[str, DirectiveOption] }
# types of doc fields that this directive handles, see sphinx.util.docfields # types of doc fields that this directive handles, see sphinx.util.docfields
doc_field_types = [] # type: List[Field] doc_field_types = [] # type: List[Field]
@ -251,7 +251,7 @@ class DefaultDomain(SphinxDirective):
required_arguments = 1 required_arguments = 1
optional_arguments = 0 optional_arguments = 0
final_argument_whitespace = False final_argument_whitespace = False
option_spec = {} # type: Dict option_spec: OptionSpec = {}
def run(self) -> List[Node]: def run(self) -> List[Node]:
domain_name = self.arguments[0].lower() domain_name = self.arguments[0].lower()

View File

@ -22,6 +22,7 @@ from sphinx.directives import optional_int
from sphinx.locale import __ from sphinx.locale import __
from sphinx.util import logging, parselinenos from sphinx.util import logging, parselinenos
from sphinx.util.docutils import SphinxDirective from sphinx.util.docutils import SphinxDirective
from sphinx.util.typing import OptionSpec
if TYPE_CHECKING: if TYPE_CHECKING:
from sphinx.application import Sphinx from sphinx.application import Sphinx
@ -39,7 +40,7 @@ class Highlight(SphinxDirective):
required_arguments = 1 required_arguments = 1
optional_arguments = 0 optional_arguments = 0
final_argument_whitespace = False final_argument_whitespace = False
option_spec = { option_spec: OptionSpec = {
'force': directives.flag, 'force': directives.flag,
'linenothreshold': directives.positive_int, 'linenothreshold': directives.positive_int,
} }
@ -103,7 +104,7 @@ class CodeBlock(SphinxDirective):
required_arguments = 0 required_arguments = 0
optional_arguments = 1 optional_arguments = 1
final_argument_whitespace = False final_argument_whitespace = False
option_spec = { option_spec: OptionSpec = {
'force': directives.flag, 'force': directives.flag,
'linenos': directives.flag, 'linenos': directives.flag,
'dedent': optional_int, 'dedent': optional_int,
@ -379,7 +380,7 @@ class LiteralInclude(SphinxDirective):
required_arguments = 1 required_arguments = 1
optional_arguments = 0 optional_arguments = 0
final_argument_whitespace = True final_argument_whitespace = True
option_spec = { option_spec: OptionSpec = {
'dedent': optional_int, 'dedent': optional_int,
'linenos': directives.flag, 'linenos': directives.flag,
'lineno-start': int, 'lineno-start': int,

View File

@ -23,6 +23,7 @@ from sphinx.util import docname_join, url_re
from sphinx.util.docutils import SphinxDirective from sphinx.util.docutils import SphinxDirective
from sphinx.util.matching import Matcher, patfilter from sphinx.util.matching import Matcher, patfilter
from sphinx.util.nodes import explicit_title_re from sphinx.util.nodes import explicit_title_re
from sphinx.util.typing import OptionSpec
if TYPE_CHECKING: if TYPE_CHECKING:
from sphinx.application import Sphinx from sphinx.application import Sphinx
@ -162,7 +163,7 @@ class Author(SphinxDirective):
required_arguments = 1 required_arguments = 1
optional_arguments = 0 optional_arguments = 0
final_argument_whitespace = True final_argument_whitespace = True
option_spec = {} # type: Dict option_spec: OptionSpec = {}
def run(self) -> List[Node]: def run(self) -> List[Node]:
if not self.config.show_authors: if not self.config.show_authors:
@ -202,7 +203,7 @@ class TabularColumns(SphinxDirective):
required_arguments = 1 required_arguments = 1
optional_arguments = 0 optional_arguments = 0
final_argument_whitespace = True final_argument_whitespace = True
option_spec = {} # type: Dict option_spec: OptionSpec = {}
def run(self) -> List[Node]: def run(self) -> List[Node]:
node = addnodes.tabular_col_spec() node = addnodes.tabular_col_spec()
@ -219,7 +220,7 @@ class Centered(SphinxDirective):
required_arguments = 1 required_arguments = 1
optional_arguments = 0 optional_arguments = 0
final_argument_whitespace = True final_argument_whitespace = True
option_spec = {} # type: Dict option_spec: OptionSpec = {}
def run(self) -> List[Node]: def run(self) -> List[Node]:
if not self.arguments: if not self.arguments:
@ -241,7 +242,7 @@ class Acks(SphinxDirective):
required_arguments = 0 required_arguments = 0
optional_arguments = 0 optional_arguments = 0
final_argument_whitespace = False final_argument_whitespace = False
option_spec = {} # type: Dict option_spec: OptionSpec = {}
def run(self) -> List[Node]: def run(self) -> List[Node]:
node = addnodes.acks() node = addnodes.acks()
@ -262,7 +263,7 @@ class HList(SphinxDirective):
required_arguments = 0 required_arguments = 0
optional_arguments = 0 optional_arguments = 0
final_argument_whitespace = False final_argument_whitespace = False
option_spec = { option_spec: OptionSpec = {
'columns': int, 'columns': int,
} }
@ -298,7 +299,7 @@ class Only(SphinxDirective):
required_arguments = 1 required_arguments = 1
optional_arguments = 0 optional_arguments = 0
final_argument_whitespace = True final_argument_whitespace = True
option_spec = {} # type: Dict option_spec: OptionSpec = {}
def run(self) -> List[Node]: def run(self) -> List[Node]:
node = addnodes.only() node = addnodes.only()

View File

@ -25,6 +25,7 @@ from sphinx.util import logging
from sphinx.util.docutils import SphinxDirective from sphinx.util.docutils import SphinxDirective
from sphinx.util.nodes import set_source_info from sphinx.util.nodes import set_source_info
from sphinx.util.osutil import SEP, os_path, relpath from sphinx.util.osutil import SEP, os_path, relpath
from sphinx.util.typing import OptionSpec
if TYPE_CHECKING: if TYPE_CHECKING:
from sphinx.application import Sphinx from sphinx.application import Sphinx
@ -140,7 +141,7 @@ class Code(SphinxDirective):
This is compatible with docutils' :rst:dir:`code` directive. This is compatible with docutils' :rst:dir:`code` directive.
""" """
optional_arguments = 1 optional_arguments = 1
option_spec = { option_spec: OptionSpec = {
'class': directives.class_option, 'class': directives.class_option,
'force': directives.flag, 'force': directives.flag,
'name': directives.unchanged, 'name': directives.unchanged,
@ -184,7 +185,7 @@ class MathDirective(SphinxDirective):
required_arguments = 0 required_arguments = 0
optional_arguments = 1 optional_arguments = 1
final_argument_whitespace = True final_argument_whitespace = True
option_spec = { option_spec: OptionSpec = {
'label': directives.unchanged, 'label': directives.unchanged,
'name': directives.unchanged, 'name': directives.unchanged,
'class': directives.class_option, 'class': directives.class_option,

View File

@ -39,6 +39,7 @@ from sphinx.util.cfamily import (ASTAttribute, ASTBaseBase, ASTBaseParenExprList
from sphinx.util.docfields import Field, TypedField from sphinx.util.docfields import Field, TypedField
from sphinx.util.docutils import SphinxDirective from sphinx.util.docutils import SphinxDirective
from sphinx.util.nodes import make_refnode from sphinx.util.nodes import make_refnode
from sphinx.util.typing import OptionSpec
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
T = TypeVar('T') T = TypeVar('T')
@ -3095,7 +3096,7 @@ class CObject(ObjectDescription[ASTDeclaration]):
names=('rtype',)), names=('rtype',)),
] ]
option_spec = { option_spec: OptionSpec = {
'noindexentry': directives.flag, 'noindexentry': directives.flag,
} }
@ -3335,7 +3336,7 @@ class CNamespaceObject(SphinxDirective):
required_arguments = 1 required_arguments = 1
optional_arguments = 0 optional_arguments = 0
final_argument_whitespace = True final_argument_whitespace = True
option_spec = {} # type: Dict option_spec: OptionSpec = {}
def run(self) -> List[Node]: def run(self) -> List[Node]:
rootSymbol = self.env.domaindata['c']['root_symbol'] rootSymbol = self.env.domaindata['c']['root_symbol']
@ -3365,7 +3366,7 @@ class CNamespacePushObject(SphinxDirective):
required_arguments = 1 required_arguments = 1
optional_arguments = 0 optional_arguments = 0
final_argument_whitespace = True final_argument_whitespace = True
option_spec = {} # type: Dict option_spec: OptionSpec = {}
def run(self) -> List[Node]: def run(self) -> List[Node]:
if self.arguments[0].strip() in ('NULL', '0', 'nullptr'): if self.arguments[0].strip() in ('NULL', '0', 'nullptr'):
@ -3396,7 +3397,7 @@ class CNamespacePopObject(SphinxDirective):
required_arguments = 0 required_arguments = 0
optional_arguments = 0 optional_arguments = 0
final_argument_whitespace = True final_argument_whitespace = True
option_spec = {} # type: Dict option_spec: OptionSpec = {}
def run(self) -> List[Node]: def run(self) -> List[Node]:
stack = self.env.temp_data.get('c:namespace_stack', None) stack = self.env.temp_data.get('c:namespace_stack', None)
@ -3550,10 +3551,10 @@ class AliasTransform(SphinxTransform):
class CAliasObject(ObjectDescription): class CAliasObject(ObjectDescription):
option_spec = { option_spec: OptionSpec = {
'maxdepth': directives.nonnegative_int, 'maxdepth': directives.nonnegative_int,
'noroot': directives.flag, 'noroot': directives.flag,
} # type: Dict }
def run(self) -> List[Node]: def run(self) -> List[Node]:
""" """

View File

@ -17,6 +17,7 @@ from sphinx import addnodes
from sphinx.domains import Domain from sphinx.domains import Domain
from sphinx.locale import _ from sphinx.locale import _
from sphinx.util.docutils import SphinxDirective from sphinx.util.docutils import SphinxDirective
from sphinx.util.typing import OptionSpec
if TYPE_CHECKING: if TYPE_CHECKING:
from sphinx.application import Sphinx from sphinx.application import Sphinx
@ -53,7 +54,7 @@ class VersionChange(SphinxDirective):
required_arguments = 1 required_arguments = 1
optional_arguments = 1 optional_arguments = 1
final_argument_whitespace = True final_argument_whitespace = True
option_spec = {} # type: Dict option_spec: OptionSpec = {}
def run(self) -> List[Node]: def run(self) -> List[Node]:
node = addnodes.versionmodified() node = addnodes.versionmodified()

View File

@ -39,6 +39,7 @@ from sphinx.util.cfamily import (ASTAttribute, ASTBaseBase, ASTBaseParenExprList
from sphinx.util.docfields import Field, GroupedField from sphinx.util.docfields import Field, GroupedField
from sphinx.util.docutils import SphinxDirective from sphinx.util.docutils import SphinxDirective
from sphinx.util.nodes import make_refnode from sphinx.util.nodes import make_refnode
from sphinx.util.typing import OptionSpec
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
T = TypeVar('T') T = TypeVar('T')
@ -6707,7 +6708,7 @@ class CPPObject(ObjectDescription[ASTDeclaration]):
names=('returns', 'return')), names=('returns', 'return')),
] ]
option_spec = { option_spec: OptionSpec = {
'noindexentry': directives.flag, 'noindexentry': directives.flag,
'tparam-line-spec': directives.flag, 'tparam-line-spec': directives.flag,
} }
@ -6973,7 +6974,7 @@ class CPPNamespaceObject(SphinxDirective):
required_arguments = 1 required_arguments = 1
optional_arguments = 0 optional_arguments = 0
final_argument_whitespace = True final_argument_whitespace = True
option_spec = {} # type: Dict option_spec: OptionSpec = {}
def run(self) -> List[Node]: def run(self) -> List[Node]:
rootSymbol = self.env.domaindata['cpp']['root_symbol'] rootSymbol = self.env.domaindata['cpp']['root_symbol']
@ -7004,7 +7005,7 @@ class CPPNamespacePushObject(SphinxDirective):
required_arguments = 1 required_arguments = 1
optional_arguments = 0 optional_arguments = 0
final_argument_whitespace = True final_argument_whitespace = True
option_spec = {} # type: Dict option_spec: OptionSpec = {}
def run(self) -> List[Node]: def run(self) -> List[Node]:
if self.arguments[0].strip() in ('NULL', '0', 'nullptr'): if self.arguments[0].strip() in ('NULL', '0', 'nullptr'):
@ -7036,7 +7037,7 @@ class CPPNamespacePopObject(SphinxDirective):
required_arguments = 0 required_arguments = 0
optional_arguments = 0 optional_arguments = 0
final_argument_whitespace = True final_argument_whitespace = True
option_spec = {} # type: Dict option_spec: OptionSpec = {}
def run(self) -> List[Node]: def run(self) -> List[Node]:
stack = self.env.temp_data.get('cpp:namespace_stack', None) stack = self.env.temp_data.get('cpp:namespace_stack', None)
@ -7213,10 +7214,10 @@ class AliasTransform(SphinxTransform):
class CPPAliasObject(ObjectDescription): class CPPAliasObject(ObjectDescription):
option_spec = { option_spec: OptionSpec = {
'maxdepth': directives.nonnegative_int, 'maxdepth': directives.nonnegative_int,
'noroot': directives.flag, 'noroot': directives.flag,
} # type: Dict }
def run(self) -> List[Node]: def run(self) -> List[Node]:
""" """

View File

@ -20,6 +20,7 @@ from sphinx.environment import BuildEnvironment
from sphinx.util import logging, split_index_msg from sphinx.util import logging, split_index_msg
from sphinx.util.docutils import ReferenceRole, SphinxDirective from sphinx.util.docutils import ReferenceRole, SphinxDirective
from sphinx.util.nodes import process_index_entry from sphinx.util.nodes import process_index_entry
from sphinx.util.typing import OptionSpec
if TYPE_CHECKING: if TYPE_CHECKING:
from sphinx.application import Sphinx from sphinx.application import Sphinx
@ -67,7 +68,7 @@ class IndexDirective(SphinxDirective):
required_arguments = 1 required_arguments = 1
optional_arguments = 0 optional_arguments = 0
final_argument_whitespace = True final_argument_whitespace = True
option_spec = { option_spec: OptionSpec = {
'name': directives.unchanged, 'name': directives.unchanged,
} }

View File

@ -28,6 +28,7 @@ from sphinx.util import logging
from sphinx.util.docfields import Field, GroupedField, TypedField from sphinx.util.docfields import Field, GroupedField, TypedField
from sphinx.util.docutils import SphinxDirective from sphinx.util.docutils import SphinxDirective
from sphinx.util.nodes import make_id, make_refnode from sphinx.util.nodes import make_id, make_refnode
from sphinx.util.typing import OptionSpec
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -47,7 +48,7 @@ class JSObject(ObjectDescription[Tuple[str, str]]):
#: based on directive nesting #: based on directive nesting
allow_nesting = False allow_nesting = False
option_spec = { option_spec: OptionSpec = {
'noindex': directives.flag, 'noindex': directives.flag,
'noindexentry': directives.flag, 'noindexentry': directives.flag,
} }
@ -253,7 +254,7 @@ class JSModule(SphinxDirective):
required_arguments = 1 required_arguments = 1
optional_arguments = 0 optional_arguments = 0
final_argument_whitespace = False final_argument_whitespace = False
option_spec = { option_spec: OptionSpec = {
'noindex': directives.flag 'noindex': directives.flag
} }

View File

@ -38,7 +38,7 @@ from sphinx.util.docfields import Field, GroupedField, TypedField
from sphinx.util.docutils import SphinxDirective from sphinx.util.docutils import SphinxDirective
from sphinx.util.inspect import signature_from_str from sphinx.util.inspect import signature_from_str
from sphinx.util.nodes import find_pending_xref_condition, make_id, make_refnode from sphinx.util.nodes import find_pending_xref_condition, make_id, make_refnode
from sphinx.util.typing import TextlikeNode from sphinx.util.typing import OptionSpec, TextlikeNode
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -357,7 +357,7 @@ class PyObject(ObjectDescription[Tuple[str, str]]):
:cvar allow_nesting: Class is an object that allows for nested namespaces :cvar allow_nesting: Class is an object that allows for nested namespaces
:vartype allow_nesting: bool :vartype allow_nesting: bool
""" """
option_spec = { option_spec: OptionSpec = {
'noindex': directives.flag, 'noindex': directives.flag,
'noindexentry': directives.flag, 'noindexentry': directives.flag,
'module': directives.unchanged, 'module': directives.unchanged,
@ -575,7 +575,7 @@ class PyObject(ObjectDescription[Tuple[str, str]]):
class PyFunction(PyObject): class PyFunction(PyObject):
"""Description of a function.""" """Description of a function."""
option_spec = PyObject.option_spec.copy() option_spec: OptionSpec = PyObject.option_spec.copy()
option_spec.update({ option_spec.update({
'async': directives.flag, 'async': directives.flag,
}) })
@ -629,7 +629,7 @@ class PyDecoratorFunction(PyFunction):
class PyVariable(PyObject): class PyVariable(PyObject):
"""Description of a variable.""" """Description of a variable."""
option_spec = PyObject.option_spec.copy() option_spec: OptionSpec = PyObject.option_spec.copy()
option_spec.update({ option_spec.update({
'type': directives.unchanged, 'type': directives.unchanged,
'value': directives.unchanged, 'value': directives.unchanged,
@ -662,7 +662,7 @@ class PyClasslike(PyObject):
Description of a class-like object (classes, interfaces, exceptions). Description of a class-like object (classes, interfaces, exceptions).
""" """
option_spec = PyObject.option_spec.copy() option_spec: OptionSpec = PyObject.option_spec.copy()
option_spec.update({ option_spec.update({
'final': directives.flag, 'final': directives.flag,
}) })
@ -689,7 +689,7 @@ class PyClasslike(PyObject):
class PyMethod(PyObject): class PyMethod(PyObject):
"""Description of a method.""" """Description of a method."""
option_spec = PyObject.option_spec.copy() option_spec: OptionSpec = PyObject.option_spec.copy()
option_spec.update({ option_spec.update({
'abstractmethod': directives.flag, 'abstractmethod': directives.flag,
'async': directives.flag, 'async': directives.flag,
@ -750,7 +750,7 @@ class PyMethod(PyObject):
class PyClassMethod(PyMethod): class PyClassMethod(PyMethod):
"""Description of a classmethod.""" """Description of a classmethod."""
option_spec = PyObject.option_spec.copy() option_spec: OptionSpec = PyObject.option_spec.copy()
def run(self) -> List[Node]: def run(self) -> List[Node]:
self.name = 'py:method' self.name = 'py:method'
@ -762,7 +762,7 @@ class PyClassMethod(PyMethod):
class PyStaticMethod(PyMethod): class PyStaticMethod(PyMethod):
"""Description of a staticmethod.""" """Description of a staticmethod."""
option_spec = PyObject.option_spec.copy() option_spec: OptionSpec = PyObject.option_spec.copy()
def run(self) -> List[Node]: def run(self) -> List[Node]:
self.name = 'py:method' self.name = 'py:method'
@ -790,7 +790,7 @@ class PyDecoratorMethod(PyMethod):
class PyAttribute(PyObject): class PyAttribute(PyObject):
"""Description of an attribute.""" """Description of an attribute."""
option_spec = PyObject.option_spec.copy() option_spec: OptionSpec = PyObject.option_spec.copy()
option_spec.update({ option_spec.update({
'type': directives.unchanged, 'type': directives.unchanged,
'value': directives.unchanged, 'value': directives.unchanged,
@ -857,7 +857,7 @@ class PyModule(SphinxDirective):
required_arguments = 1 required_arguments = 1
optional_arguments = 0 optional_arguments = 0
final_argument_whitespace = False final_argument_whitespace = False
option_spec = { option_spec: OptionSpec = {
'platform': lambda x: x, 'platform': lambda x: x,
'synopsis': lambda x: x, 'synopsis': lambda x: x,
'noindex': directives.flag, 'noindex': directives.flag,
@ -921,7 +921,7 @@ class PyCurrentModule(SphinxDirective):
required_arguments = 1 required_arguments = 1
optional_arguments = 0 optional_arguments = 0
final_argument_whitespace = False final_argument_whitespace = False
option_spec = {} # type: Dict option_spec: OptionSpec = {}
def run(self) -> List[Node]: def run(self) -> List[Node]:
modname = self.arguments[0].strip() modname = self.arguments[0].strip()

View File

@ -25,6 +25,7 @@ from sphinx.locale import _, __
from sphinx.roles import XRefRole from sphinx.roles import XRefRole
from sphinx.util import logging from sphinx.util import logging
from sphinx.util.nodes import make_id, make_refnode from sphinx.util.nodes import make_id, make_refnode
from sphinx.util.typing import OptionSpec
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -117,7 +118,7 @@ class ReSTDirectiveOption(ReSTMarkup):
""" """
Description of an option for reST directive. Description of an option for reST directive.
""" """
option_spec = ReSTMarkup.option_spec.copy() option_spec: OptionSpec = ReSTMarkup.option_spec.copy()
option_spec.update({ option_spec.update({
'type': directives.unchanged, 'type': directives.unchanged,
}) })

View File

@ -30,7 +30,7 @@ from sphinx.roles import XRefRole
from sphinx.util import docname_join, logging, ws_re from sphinx.util import docname_join, logging, ws_re
from sphinx.util.docutils import SphinxDirective from sphinx.util.docutils import SphinxDirective
from sphinx.util.nodes import clean_astext, make_id, make_refnode from sphinx.util.nodes import clean_astext, make_id, make_refnode
from sphinx.util.typing import RoleFunction from sphinx.util.typing import OptionSpec, RoleFunction
if TYPE_CHECKING: if TYPE_CHECKING:
from sphinx.application import Sphinx from sphinx.application import Sphinx
@ -132,7 +132,7 @@ class Target(SphinxDirective):
required_arguments = 1 required_arguments = 1
optional_arguments = 0 optional_arguments = 0
final_argument_whitespace = True final_argument_whitespace = True
option_spec = {} # type: Dict option_spec: OptionSpec = {}
def run(self) -> List[Node]: def run(self) -> List[Node]:
# normalize whitespace in fullname like XRefRole does # normalize whitespace in fullname like XRefRole does
@ -265,7 +265,7 @@ class Program(SphinxDirective):
required_arguments = 1 required_arguments = 1
optional_arguments = 0 optional_arguments = 0
final_argument_whitespace = True final_argument_whitespace = True
option_spec = {} # type: Dict option_spec: OptionSpec = {}
def run(self) -> List[Node]: def run(self) -> List[Node]:
program = ws_re.sub('-', self.arguments[0].strip()) program = ws_re.sub('-', self.arguments[0].strip())
@ -329,7 +329,7 @@ class Glossary(SphinxDirective):
required_arguments = 0 required_arguments = 0
optional_arguments = 0 optional_arguments = 0
final_argument_whitespace = False final_argument_whitespace = False
option_spec = { option_spec: OptionSpec = {
'sorted': directives.flag, 'sorted': directives.flag,
} }
@ -482,7 +482,7 @@ class ProductionList(SphinxDirective):
required_arguments = 1 required_arguments = 1
optional_arguments = 0 optional_arguments = 0
final_argument_whitespace = True final_argument_whitespace = True
option_spec = {} # type: Dict option_spec: OptionSpec = {}
def run(self) -> List[Node]: def run(self) -> List[Node]:
domain = cast(StandardDomain, self.env.get_domain('std')) domain = cast(StandardDomain, self.env.get_domain('std'))

View File

@ -33,7 +33,7 @@ from sphinx.util import inspect, logging
from sphinx.util.docstrings import extract_metadata, prepare_docstring from sphinx.util.docstrings import extract_metadata, prepare_docstring
from sphinx.util.inspect import (evaluate_signature, getdoc, object_description, safe_getattr, from sphinx.util.inspect import (evaluate_signature, getdoc, object_description, safe_getattr,
stringify_signature) stringify_signature)
from sphinx.util.typing import get_type_hints, restify from sphinx.util.typing import OptionSpec, get_type_hints, restify
from sphinx.util.typing import stringify as stringify_typehint from sphinx.util.typing import stringify as stringify_typehint
if TYPE_CHECKING: if TYPE_CHECKING:
@ -309,7 +309,9 @@ class Documenter:
#: true if the generated content may contain titles #: true if the generated content may contain titles
titles_allowed = False titles_allowed = False
option_spec = {'noindex': bool_option} # type: Dict[str, Callable] option_spec: OptionSpec = {
'noindex': bool_option
}
def get_attr(self, obj: Any, name: str, *defargs: Any) -> Any: def get_attr(self, obj: Any, name: str, *defargs: Any) -> Any:
"""getattr() override for types such as Zope interfaces.""" """getattr() override for types such as Zope interfaces."""
@ -970,7 +972,7 @@ class ModuleDocumenter(Documenter):
content_indent = '' content_indent = ''
titles_allowed = True titles_allowed = True
option_spec = { option_spec: OptionSpec = {
'members': members_option, 'undoc-members': bool_option, 'members': members_option, 'undoc-members': bool_option,
'noindex': bool_option, 'inherited-members': inherited_members_option, 'noindex': bool_option, 'inherited-members': inherited_members_option,
'show-inheritance': bool_option, 'synopsis': identity, 'show-inheritance': bool_option, 'synopsis': identity,
@ -978,7 +980,7 @@ class ModuleDocumenter(Documenter):
'member-order': member_order_option, 'exclude-members': exclude_members_option, 'member-order': member_order_option, 'exclude-members': exclude_members_option,
'private-members': members_option, 'special-members': members_option, 'private-members': members_option, 'special-members': members_option,
'imported-members': bool_option, 'ignore-module-all': bool_option 'imported-members': bool_option, 'ignore-module-all': bool_option
} # type: Dict[str, Callable] }
def __init__(self, *args: Any) -> None: def __init__(self, *args: Any) -> None:
super().__init__(*args) super().__init__(*args)
@ -1419,13 +1421,13 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
""" """
objtype = 'class' objtype = 'class'
member_order = 20 member_order = 20
option_spec = { option_spec: OptionSpec = {
'members': members_option, 'undoc-members': bool_option, 'members': members_option, 'undoc-members': bool_option,
'noindex': bool_option, 'inherited-members': inherited_members_option, 'noindex': bool_option, 'inherited-members': inherited_members_option,
'show-inheritance': bool_option, 'member-order': member_order_option, 'show-inheritance': bool_option, 'member-order': member_order_option,
'exclude-members': exclude_members_option, 'exclude-members': exclude_members_option,
'private-members': members_option, 'special-members': members_option, 'private-members': members_option, 'special-members': members_option,
} # type: Dict[str, Callable] }
_signature_class = None # type: Any _signature_class = None # type: Any
_signature_method_name = None # type: str _signature_method_name = None # type: str
@ -1874,7 +1876,7 @@ class DataDocumenter(GenericAliasMixin, NewTypeMixin, TypeVarMixin,
objtype = 'data' objtype = 'data'
member_order = 40 member_order = 40
priority = -10 priority = -10
option_spec = dict(ModuleLevelDocumenter.option_spec) option_spec: OptionSpec = dict(ModuleLevelDocumenter.option_spec)
option_spec["annotation"] = annotation_option option_spec["annotation"] = annotation_option
option_spec["no-value"] = bool_option option_spec["no-value"] = bool_option
@ -2358,7 +2360,7 @@ class AttributeDocumenter(GenericAliasMixin, NewTypeMixin, SlotsMixin, # type:
""" """
objtype = 'attribute' objtype = 'attribute'
member_order = 60 member_order = 60
option_spec = dict(ModuleLevelDocumenter.option_spec) option_spec: OptionSpec = dict(ModuleLevelDocumenter.option_spec)
option_spec["annotation"] = annotation_option option_spec["annotation"] = annotation_option
option_spec["no-value"] = bool_option option_spec["no-value"] = bool_option

View File

@ -85,6 +85,7 @@ from sphinx.util import logging, rst
from sphinx.util.docutils import (NullReporter, SphinxDirective, SphinxRole, new_document, from sphinx.util.docutils import (NullReporter, SphinxDirective, SphinxRole, new_document,
switch_source_input) switch_source_input)
from sphinx.util.matching import Matcher from sphinx.util.matching import Matcher
from sphinx.util.typing import OptionSpec
from sphinx.writers.html import HTMLTranslator from sphinx.writers.html import HTMLTranslator
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -225,7 +226,7 @@ class Autosummary(SphinxDirective):
optional_arguments = 0 optional_arguments = 0
final_argument_whitespace = False final_argument_whitespace = False
has_content = True has_content = True
option_spec = { option_spec: OptionSpec = {
'caption': directives.unchanged_required, 'caption': directives.unchanged_required,
'toctree': directives.unchanged, 'toctree': directives.unchanged,
'nosignatures': directives.flag, 'nosignatures': directives.flag,

View File

@ -31,6 +31,7 @@ from sphinx.util import logging
from sphinx.util.console import bold # type: ignore from sphinx.util.console import bold # type: ignore
from sphinx.util.docutils import SphinxDirective from sphinx.util.docutils import SphinxDirective
from sphinx.util.osutil import relpath from sphinx.util.osutil import relpath
from sphinx.util.typing import OptionSpec
if TYPE_CHECKING: if TYPE_CHECKING:
from sphinx.application import Sphinx from sphinx.application import Sphinx
@ -150,15 +151,19 @@ class TestDirective(SphinxDirective):
class TestsetupDirective(TestDirective): class TestsetupDirective(TestDirective):
option_spec = {'skipif': directives.unchanged_required} # type: Dict option_spec: OptionSpec = {
'skipif': directives.unchanged_required
}
class TestcleanupDirective(TestDirective): class TestcleanupDirective(TestDirective):
option_spec = {'skipif': directives.unchanged_required} # type: Dict option_spec: OptionSpec = {
'skipif': directives.unchanged_required
}
class DoctestDirective(TestDirective): class DoctestDirective(TestDirective):
option_spec = { option_spec: OptionSpec = {
'hide': directives.flag, 'hide': directives.flag,
'no-trim-doctest-flags': directives.flag, 'no-trim-doctest-flags': directives.flag,
'options': directives.unchanged, 'options': directives.unchanged,
@ -169,7 +174,7 @@ class DoctestDirective(TestDirective):
class TestcodeDirective(TestDirective): class TestcodeDirective(TestDirective):
option_spec = { option_spec: OptionSpec = {
'hide': directives.flag, 'hide': directives.flag,
'no-trim-doctest-flags': directives.flag, 'no-trim-doctest-flags': directives.flag,
'pyversion': directives.unchanged_required, 'pyversion': directives.unchanged_required,
@ -179,7 +184,7 @@ class TestcodeDirective(TestDirective):
class TestoutputDirective(TestDirective): class TestoutputDirective(TestDirective):
option_spec = { option_spec: OptionSpec = {
'hide': directives.flag, 'hide': directives.flag,
'no-trim-doctest-flags': directives.flag, 'no-trim-doctest-flags': directives.flag,
'options': directives.unchanged, 'options': directives.unchanged,

View File

@ -30,6 +30,7 @@ from sphinx.util.fileutil import copy_asset
from sphinx.util.i18n import search_image_for_language from sphinx.util.i18n import search_image_for_language
from sphinx.util.nodes import set_source_info from sphinx.util.nodes import set_source_info
from sphinx.util.osutil import ensuredir from sphinx.util.osutil import ensuredir
from sphinx.util.typing import OptionSpec
from sphinx.writers.html import HTMLTranslator from sphinx.writers.html import HTMLTranslator
from sphinx.writers.latex import LaTeXTranslator from sphinx.writers.latex import LaTeXTranslator
from sphinx.writers.manpage import ManualPageTranslator from sphinx.writers.manpage import ManualPageTranslator
@ -113,7 +114,7 @@ class Graphviz(SphinxDirective):
required_arguments = 0 required_arguments = 0
optional_arguments = 1 optional_arguments = 1
final_argument_whitespace = False final_argument_whitespace = False
option_spec = { option_spec: OptionSpec = {
'alt': directives.unchanged, 'alt': directives.unchanged,
'align': align_spec, 'align': align_spec,
'caption': directives.unchanged, 'caption': directives.unchanged,
@ -181,7 +182,7 @@ class GraphvizSimple(SphinxDirective):
required_arguments = 1 required_arguments = 1
optional_arguments = 0 optional_arguments = 0
final_argument_whitespace = False final_argument_whitespace = False
option_spec = { option_spec: OptionSpec = {
'alt': directives.unchanged, 'alt': directives.unchanged,
'align': align_spec, 'align': align_spec,
'caption': directives.unchanged, 'caption': directives.unchanged,

View File

@ -28,6 +28,7 @@ import sphinx
from sphinx.application import Sphinx from sphinx.application import Sphinx
from sphinx.util.docutils import SphinxDirective from sphinx.util.docutils import SphinxDirective
from sphinx.util.nodes import nested_parse_with_titles from sphinx.util.nodes import nested_parse_with_titles
from sphinx.util.typing import OptionSpec
class ifconfig(nodes.Element): class ifconfig(nodes.Element):
@ -40,7 +41,7 @@ class IfConfig(SphinxDirective):
required_arguments = 1 required_arguments = 1
optional_arguments = 0 optional_arguments = 0
final_argument_whitespace = True final_argument_whitespace = True
option_spec = {} # type: Dict option_spec: OptionSpec = {}
def run(self) -> List[Node]: def run(self) -> List[Node]:
node = ifconfig() node = ifconfig()

View File

@ -53,6 +53,7 @@ from sphinx.ext.graphviz import (figure_wrapper, graphviz, render_dot_html, rend
render_dot_texinfo) render_dot_texinfo)
from sphinx.util import md5 from sphinx.util import md5
from sphinx.util.docutils import SphinxDirective from sphinx.util.docutils import SphinxDirective
from sphinx.util.typing import OptionSpec
from sphinx.writers.html import HTMLTranslator from sphinx.writers.html import HTMLTranslator
from sphinx.writers.latex import LaTeXTranslator from sphinx.writers.latex import LaTeXTranslator
from sphinx.writers.texinfo import TexinfoTranslator from sphinx.writers.texinfo import TexinfoTranslator
@ -331,7 +332,7 @@ class InheritanceDiagram(SphinxDirective):
required_arguments = 1 required_arguments = 1
optional_arguments = 0 optional_arguments = 0
final_argument_whitespace = True final_argument_whitespace = True
option_spec = { option_spec: OptionSpec = {
'parts': int, 'parts': int,
'private-bases': directives.flag, 'private-bases': directives.flag,
'caption': directives.unchanged, 'caption': directives.unchanged,

View File

@ -27,6 +27,7 @@ from sphinx.errors import NoUri
from sphinx.locale import _, __ from sphinx.locale import _, __
from sphinx.util import logging, texescape from sphinx.util import logging, texescape
from sphinx.util.docutils import SphinxDirective, new_document from sphinx.util.docutils import SphinxDirective, new_document
from sphinx.util.typing import OptionSpec
from sphinx.writers.html import HTMLTranslator from sphinx.writers.html import HTMLTranslator
from sphinx.writers.latex import LaTeXTranslator from sphinx.writers.latex import LaTeXTranslator
@ -51,7 +52,7 @@ class Todo(BaseAdmonition, SphinxDirective):
required_arguments = 0 required_arguments = 0
optional_arguments = 0 optional_arguments = 0
final_argument_whitespace = False final_argument_whitespace = False
option_spec = { option_spec: OptionSpec = {
'class': directives.class_option, 'class': directives.class_option,
'name': directives.unchanged, 'name': directives.unchanged,
} }
@ -110,7 +111,7 @@ class TodoList(SphinxDirective):
required_arguments = 0 required_arguments = 0
optional_arguments = 0 optional_arguments = 0
final_argument_whitespace = False final_argument_whitespace = False
option_spec = {} # type: Dict option_spec: OptionSpec = {}
def run(self) -> List[Node]: def run(self) -> List[Node]:
# Simply insert an empty todolist node which will be replaced later # Simply insert an empty todolist node which will be replaced later

View File

@ -16,6 +16,8 @@ from typing import Any, Callable, Dict, Generator, List, Optional, Tuple, TypeVa
from docutils import nodes from docutils import nodes
from docutils.parsers.rst.states import Inliner from docutils.parsers.rst.states import Inliner
from sphinx.deprecation import RemovedInSphinx60Warning, deprecated_alias
if sys.version_info > (3, 7): if sys.version_info > (3, 7):
from typing import ForwardRef from typing import ForwardRef
else: else:
@ -40,9 +42,6 @@ if False:
from typing import Type # NOQA # for python3.5.1 from typing import Type # NOQA # for python3.5.1
# An entry of Directive.option_spec
DirectiveOption = Callable[[str], Any]
# Text like nodes which are initialized with text and rawsource # Text like nodes which are initialized with text and rawsource
TextlikeNode = Union[nodes.Text, nodes.TextElement] TextlikeNode = Union[nodes.Text, nodes.TextElement]
@ -56,6 +55,9 @@ PathMatcher = Callable[[str], bool]
RoleFunction = Callable[[str, str, str, int, Inliner, Dict[str, Any], List[str]], RoleFunction = Callable[[str, str, str, int, Inliner, Dict[str, Any], List[str]],
Tuple[List[nodes.Node], List[nodes.system_message]]] Tuple[List[nodes.Node], List[nodes.system_message]]]
# A option spec for directive
OptionSpec = Dict[str, Callable[[Optional[str]], Any]]
# title getter functions for enumerable nodes (see sphinx.domains.std) # title getter functions for enumerable nodes (see sphinx.domains.std)
TitleGetter = Callable[[nodes.Node], str] TitleGetter = Callable[[nodes.Node], str]
@ -405,3 +407,10 @@ def _stringify_py36(annotation: Any) -> str:
return 'Union[%s]' % param_str return 'Union[%s]' % param_str
return qualname return qualname
deprecated_alias('sphinx.util.typing',
{
'DirectiveOption': Callable[[str], Any],
},
RemovedInSphinx60Warning)