summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES1
-rw-r--r--doc/extdev/deprecated.rst5
-rw-r--r--sphinx/directives/__init__.py8
-rw-r--r--sphinx/directives/code.py7
-rw-r--r--sphinx/directives/other.py13
-rw-r--r--sphinx/directives/patches.py5
-rw-r--r--sphinx/domains/c.py13
-rw-r--r--sphinx/domains/changeset.py3
-rw-r--r--sphinx/domains/cpp.py13
-rw-r--r--sphinx/domains/index.py3
-rw-r--r--sphinx/domains/javascript.py5
-rw-r--r--sphinx/domains/python.py22
-rw-r--r--sphinx/domains/rst.py3
-rw-r--r--sphinx/domains/std.py10
-rw-r--r--sphinx/ext/autodoc/__init__.py18
-rw-r--r--sphinx/ext/autosummary/__init__.py3
-rw-r--r--sphinx/ext/doctest.py15
-rw-r--r--sphinx/ext/graphviz.py5
-rw-r--r--sphinx/ext/ifconfig.py3
-rw-r--r--sphinx/ext/inheritance_diagram.py3
-rw-r--r--sphinx/ext/todo.py5
-rw-r--r--sphinx/util/typing.py15
22 files changed, 107 insertions, 71 deletions
diff --git a/CHANGES b/CHANGES
index d59dc9f52..4d5dc1623 100644
--- a/CHANGES
+++ b/CHANGES
@@ -57,6 +57,7 @@ Deprecated
* ``sphinx.util.pycompat.convert_with_2to3()``
* ``sphinx.util.pycompat.execfile_()``
* ``sphinx.util.smartypants``
+* ``sphinx.util.typing.DirectiveOption``
Features added
--------------
diff --git a/doc/extdev/deprecated.rst b/doc/extdev/deprecated.rst
index 96bc84ff3..3fdb55e2c 100644
--- a/doc/extdev/deprecated.rst
+++ b/doc/extdev/deprecated.rst
@@ -72,6 +72,11 @@ The following is a list of deprecated interfaces.
- 6.0
- ``docutils.utils.smartyquotes``
+ * - ``sphinx.util.typing.DirectiveOption``
+ - 4.0
+ - 6.0
+ - N/A
+
* - pending_xref node for viewcode extension
- 3.5
- 5.0
diff --git a/sphinx/directives/__init__.py b/sphinx/directives/__init__.py
index d4c82c9f3..f40144809 100644
--- a/sphinx/directives/__init__.py
+++ b/sphinx/directives/__init__.py
@@ -21,7 +21,7 @@ from sphinx.deprecation import RemovedInSphinx50Warning, deprecated_alias
from sphinx.util import docutils
from sphinx.util.docfields import DocFieldTransformer, Field, TypedField
from sphinx.util.docutils import SphinxDirective
-from sphinx.util.typing import DirectiveOption
+from sphinx.util.typing import OptionSpec
if TYPE_CHECKING:
from sphinx.application import Sphinx
@@ -58,9 +58,9 @@ class ObjectDescription(SphinxDirective, Generic[T]):
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = True
- option_spec = {
+ option_spec: OptionSpec = {
'noindex': directives.flag,
- } # type: Dict[str, DirectiveOption]
+ }
# types of doc fields that this directive handles, see sphinx.util.docfields
doc_field_types = [] # type: List[Field]
@@ -251,7 +251,7 @@ class DefaultDomain(SphinxDirective):
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = False
- option_spec = {} # type: Dict
+ option_spec: OptionSpec = {}
def run(self) -> List[Node]:
domain_name = self.arguments[0].lower()
diff --git a/sphinx/directives/code.py b/sphinx/directives/code.py
index f5cd92b82..04b81cef5 100644
--- a/sphinx/directives/code.py
+++ b/sphinx/directives/code.py
@@ -22,6 +22,7 @@ from sphinx.directives import optional_int
from sphinx.locale import __
from sphinx.util import logging, parselinenos
from sphinx.util.docutils import SphinxDirective
+from sphinx.util.typing import OptionSpec
if TYPE_CHECKING:
from sphinx.application import Sphinx
@@ -39,7 +40,7 @@ class Highlight(SphinxDirective):
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = False
- option_spec = {
+ option_spec: OptionSpec = {
'force': directives.flag,
'linenothreshold': directives.positive_int,
}
@@ -103,7 +104,7 @@ class CodeBlock(SphinxDirective):
required_arguments = 0
optional_arguments = 1
final_argument_whitespace = False
- option_spec = {
+ option_spec: OptionSpec = {
'force': directives.flag,
'linenos': directives.flag,
'dedent': optional_int,
@@ -379,7 +380,7 @@ class LiteralInclude(SphinxDirective):
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = True
- option_spec = {
+ option_spec: OptionSpec = {
'dedent': optional_int,
'linenos': directives.flag,
'lineno-start': int,
diff --git a/sphinx/directives/other.py b/sphinx/directives/other.py
index 7dd6252e2..1daa3c4a5 100644
--- a/sphinx/directives/other.py
+++ b/sphinx/directives/other.py
@@ -23,6 +23,7 @@ from sphinx.util import docname_join, url_re
from sphinx.util.docutils import SphinxDirective
from sphinx.util.matching import Matcher, patfilter
from sphinx.util.nodes import explicit_title_re
+from sphinx.util.typing import OptionSpec
if TYPE_CHECKING:
from sphinx.application import Sphinx
@@ -162,7 +163,7 @@ class Author(SphinxDirective):
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = True
- option_spec = {} # type: Dict
+ option_spec: OptionSpec = {}
def run(self) -> List[Node]:
if not self.config.show_authors:
@@ -202,7 +203,7 @@ class TabularColumns(SphinxDirective):
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = True
- option_spec = {} # type: Dict
+ option_spec: OptionSpec = {}
def run(self) -> List[Node]:
node = addnodes.tabular_col_spec()
@@ -219,7 +220,7 @@ class Centered(SphinxDirective):
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = True
- option_spec = {} # type: Dict
+ option_spec: OptionSpec = {}
def run(self) -> List[Node]:
if not self.arguments:
@@ -241,7 +242,7 @@ class Acks(SphinxDirective):
required_arguments = 0
optional_arguments = 0
final_argument_whitespace = False
- option_spec = {} # type: Dict
+ option_spec: OptionSpec = {}
def run(self) -> List[Node]:
node = addnodes.acks()
@@ -262,7 +263,7 @@ class HList(SphinxDirective):
required_arguments = 0
optional_arguments = 0
final_argument_whitespace = False
- option_spec = {
+ option_spec: OptionSpec = {
'columns': int,
}
@@ -298,7 +299,7 @@ class Only(SphinxDirective):
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = True
- option_spec = {} # type: Dict
+ option_spec: OptionSpec = {}
def run(self) -> List[Node]:
node = addnodes.only()
diff --git a/sphinx/directives/patches.py b/sphinx/directives/patches.py
index 1c3cfd853..b4c978474 100644
--- a/sphinx/directives/patches.py
+++ b/sphinx/directives/patches.py
@@ -25,6 +25,7 @@ from sphinx.util import logging
from sphinx.util.docutils import SphinxDirective
from sphinx.util.nodes import set_source_info
from sphinx.util.osutil import SEP, os_path, relpath
+from sphinx.util.typing import OptionSpec
if TYPE_CHECKING:
from sphinx.application import Sphinx
@@ -140,7 +141,7 @@ class Code(SphinxDirective):
This is compatible with docutils' :rst:dir:`code` directive.
"""
optional_arguments = 1
- option_spec = {
+ option_spec: OptionSpec = {
'class': directives.class_option,
'force': directives.flag,
'name': directives.unchanged,
@@ -184,7 +185,7 @@ class MathDirective(SphinxDirective):
required_arguments = 0
optional_arguments = 1
final_argument_whitespace = True
- option_spec = {
+ option_spec: OptionSpec = {
'label': directives.unchanged,
'name': directives.unchanged,
'class': directives.class_option,
diff --git a/sphinx/domains/c.py b/sphinx/domains/c.py
index 0fecbad6d..1b7a5fb60 100644
--- a/sphinx/domains/c.py
+++ b/sphinx/domains/c.py
@@ -39,6 +39,7 @@ from sphinx.util.cfamily import (ASTAttribute, ASTBaseBase, ASTBaseParenExprList
from sphinx.util.docfields import Field, TypedField
from sphinx.util.docutils import SphinxDirective
from sphinx.util.nodes import make_refnode
+from sphinx.util.typing import OptionSpec
logger = logging.getLogger(__name__)
T = TypeVar('T')
@@ -3095,7 +3096,7 @@ class CObject(ObjectDescription[ASTDeclaration]):
names=('rtype',)),
]
- option_spec = {
+ option_spec: OptionSpec = {
'noindexentry': directives.flag,
}
@@ -3335,7 +3336,7 @@ class CNamespaceObject(SphinxDirective):
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = True
- option_spec = {} # type: Dict
+ option_spec: OptionSpec = {}
def run(self) -> List[Node]:
rootSymbol = self.env.domaindata['c']['root_symbol']
@@ -3365,7 +3366,7 @@ class CNamespacePushObject(SphinxDirective):
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = True
- option_spec = {} # type: Dict
+ option_spec: OptionSpec = {}
def run(self) -> List[Node]:
if self.arguments[0].strip() in ('NULL', '0', 'nullptr'):
@@ -3396,7 +3397,7 @@ class CNamespacePopObject(SphinxDirective):
required_arguments = 0
optional_arguments = 0
final_argument_whitespace = True
- option_spec = {} # type: Dict
+ option_spec: OptionSpec = {}
def run(self) -> List[Node]:
stack = self.env.temp_data.get('c:namespace_stack', None)
@@ -3550,10 +3551,10 @@ class AliasTransform(SphinxTransform):
class CAliasObject(ObjectDescription):
- option_spec = {
+ option_spec: OptionSpec = {
'maxdepth': directives.nonnegative_int,
'noroot': directives.flag,
- } # type: Dict
+ }
def run(self) -> List[Node]:
"""
diff --git a/sphinx/domains/changeset.py b/sphinx/domains/changeset.py
index 33234d6e0..23a3375ce 100644
--- a/sphinx/domains/changeset.py
+++ b/sphinx/domains/changeset.py
@@ -17,6 +17,7 @@ from sphinx import addnodes
from sphinx.domains import Domain
from sphinx.locale import _
from sphinx.util.docutils import SphinxDirective
+from sphinx.util.typing import OptionSpec
if TYPE_CHECKING:
from sphinx.application import Sphinx
@@ -53,7 +54,7 @@ class VersionChange(SphinxDirective):
required_arguments = 1
optional_arguments = 1
final_argument_whitespace = True
- option_spec = {} # type: Dict
+ option_spec: OptionSpec = {}
def run(self) -> List[Node]:
node = addnodes.versionmodified()
diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py
index 3bd764de5..9637654c9 100644
--- a/sphinx/domains/cpp.py
+++ b/sphinx/domains/cpp.py
@@ -39,6 +39,7 @@ from sphinx.util.cfamily import (ASTAttribute, ASTBaseBase, ASTBaseParenExprList
from sphinx.util.docfields import Field, GroupedField
from sphinx.util.docutils import SphinxDirective
from sphinx.util.nodes import make_refnode
+from sphinx.util.typing import OptionSpec
logger = logging.getLogger(__name__)
T = TypeVar('T')
@@ -6707,7 +6708,7 @@ class CPPObject(ObjectDescription[ASTDeclaration]):
names=('returns', 'return')),
]
- option_spec = {
+ option_spec: OptionSpec = {
'noindexentry': directives.flag,
'tparam-line-spec': directives.flag,
}
@@ -6973,7 +6974,7 @@ class CPPNamespaceObject(SphinxDirective):
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = True
- option_spec = {} # type: Dict
+ option_spec: OptionSpec = {}
def run(self) -> List[Node]:
rootSymbol = self.env.domaindata['cpp']['root_symbol']
@@ -7004,7 +7005,7 @@ class CPPNamespacePushObject(SphinxDirective):
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = True
- option_spec = {} # type: Dict
+ option_spec: OptionSpec = {}
def run(self) -> List[Node]:
if self.arguments[0].strip() in ('NULL', '0', 'nullptr'):
@@ -7036,7 +7037,7 @@ class CPPNamespacePopObject(SphinxDirective):
required_arguments = 0
optional_arguments = 0
final_argument_whitespace = True
- option_spec = {} # type: Dict
+ option_spec: OptionSpec = {}
def run(self) -> List[Node]:
stack = self.env.temp_data.get('cpp:namespace_stack', None)
@@ -7213,10 +7214,10 @@ class AliasTransform(SphinxTransform):
class CPPAliasObject(ObjectDescription):
- option_spec = {
+ option_spec: OptionSpec = {
'maxdepth': directives.nonnegative_int,
'noroot': directives.flag,
- } # type: Dict
+ }
def run(self) -> List[Node]:
"""
diff --git a/sphinx/domains/index.py b/sphinx/domains/index.py
index fd1a76613..9ecfae439 100644
--- a/sphinx/domains/index.py
+++ b/sphinx/domains/index.py
@@ -20,6 +20,7 @@ from sphinx.environment import BuildEnvironment
from sphinx.util import logging, split_index_msg
from sphinx.util.docutils import ReferenceRole, SphinxDirective
from sphinx.util.nodes import process_index_entry
+from sphinx.util.typing import OptionSpec
if TYPE_CHECKING:
from sphinx.application import Sphinx
@@ -67,7 +68,7 @@ class IndexDirective(SphinxDirective):
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = True
- option_spec = {
+ option_spec: OptionSpec = {
'name': directives.unchanged,
}
diff --git a/sphinx/domains/javascript.py b/sphinx/domains/javascript.py
index f612fb914..b34cff509 100644
--- a/sphinx/domains/javascript.py
+++ b/sphinx/domains/javascript.py
@@ -28,6 +28,7 @@ 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_id, make_refnode
+from sphinx.util.typing import OptionSpec
logger = logging.getLogger(__name__)
@@ -47,7 +48,7 @@ class JSObject(ObjectDescription[Tuple[str, str]]):
#: based on directive nesting
allow_nesting = False
- option_spec = {
+ option_spec: OptionSpec = {
'noindex': directives.flag,
'noindexentry': directives.flag,
}
@@ -253,7 +254,7 @@ class JSModule(SphinxDirective):
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = False
- option_spec = {
+ option_spec: OptionSpec = {
'noindex': directives.flag
}
diff --git a/sphinx/domains/python.py b/sphinx/domains/python.py
index 40a67f82c..a1e892f4c 100644
--- a/sphinx/domains/python.py
+++ b/sphinx/domains/python.py
@@ -38,7 +38,7 @@ from sphinx.util.docfields import Field, GroupedField, TypedField
from sphinx.util.docutils import SphinxDirective
from sphinx.util.inspect import signature_from_str
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__)
@@ -357,7 +357,7 @@ class PyObject(ObjectDescription[Tuple[str, str]]):
:cvar allow_nesting: Class is an object that allows for nested namespaces
:vartype allow_nesting: bool
"""
- option_spec = {
+ option_spec: OptionSpec = {
'noindex': directives.flag,
'noindexentry': directives.flag,
'module': directives.unchanged,
@@ -575,7 +575,7 @@ class PyObject(ObjectDescription[Tuple[str, str]]):
class PyFunction(PyObject):
"""Description of a function."""
- option_spec = PyObject.option_spec.copy()
+ option_spec: OptionSpec = PyObject.option_spec.copy()
option_spec.update({
'async': directives.flag,
})
@@ -629,7 +629,7 @@ class PyDecoratorFunction(PyFunction):
class PyVariable(PyObject):
"""Description of a variable."""
- option_spec = PyObject.option_spec.copy()
+ option_spec: OptionSpec = PyObject.option_spec.copy()
option_spec.update({
'type': directives.unchanged,
'value': directives.unchanged,
@@ -662,7 +662,7 @@ class PyClasslike(PyObject):
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({
'final': directives.flag,
})
@@ -689,7 +689,7 @@ class PyClasslike(PyObject):
class PyMethod(PyObject):
"""Description of a method."""
- option_spec = PyObject.option_spec.copy()
+ option_spec: OptionSpec = PyObject.option_spec.copy()
option_spec.update({
'abstractmethod': directives.flag,
'async': directives.flag,
@@ -750,7 +750,7 @@ class PyMethod(PyObject):
class PyClassMethod(PyMethod):
"""Description of a classmethod."""
- option_spec = PyObject.option_spec.copy()
+ option_spec: OptionSpec = PyObject.option_spec.copy()
def run(self) -> List[Node]:
self.name = 'py:method'
@@ -762,7 +762,7 @@ class PyClassMethod(PyMethod):
class PyStaticMethod(PyMethod):
"""Description of a staticmethod."""
- option_spec = PyObject.option_spec.copy()
+ option_spec: OptionSpec = PyObject.option_spec.copy()
def run(self) -> List[Node]:
self.name = 'py:method'
@@ -790,7 +790,7 @@ class PyDecoratorMethod(PyMethod):
class PyAttribute(PyObject):
"""Description of an attribute."""
- option_spec = PyObject.option_spec.copy()
+ option_spec: OptionSpec = PyObject.option_spec.copy()
option_spec.update({
'type': directives.unchanged,
'value': directives.unchanged,
@@ -857,7 +857,7 @@ class PyModule(SphinxDirective):
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = False
- option_spec = {
+ option_spec: OptionSpec = {
'platform': lambda x: x,
'synopsis': lambda x: x,
'noindex': directives.flag,
@@ -921,7 +921,7 @@ class PyCurrentModule(SphinxDirective):
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = False
- option_spec = {} # type: Dict
+ option_spec: OptionSpec = {}
def run(self) -> List[Node]:
modname = self.arguments[0].strip()
diff --git a/sphinx/domains/rst.py b/sphinx/domains/rst.py
index 07bf46b75..6b4f1c0ff 100644
--- a/sphinx/domains/rst.py
+++ b/sphinx/domains/rst.py
@@ -25,6 +25,7 @@ from sphinx.locale import _, __
from sphinx.roles import XRefRole
from sphinx.util import logging
from sphinx.util.nodes import make_id, make_refnode
+from sphinx.util.typing import OptionSpec
logger = logging.getLogger(__name__)
@@ -117,7 +118,7 @@ class ReSTDirectiveOption(ReSTMarkup):
"""
Description of an option for reST directive.
"""
- option_spec = ReSTMarkup.option_spec.copy()
+ option_spec: OptionSpec = ReSTMarkup.option_spec.copy()
option_spec.update({
'type': directives.unchanged,
})
diff --git a/sphinx/domains/std.py b/sphinx/domains/std.py
index 8b10c8547..274c29c87 100644
--- a/sphinx/domains/std.py
+++ b/sphinx/domains/std.py
@@ -30,7 +30,7 @@ from sphinx.roles import XRefRole
from sphinx.util import docname_join, logging, ws_re
from sphinx.util.docutils import SphinxDirective
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:
from sphinx.application import Sphinx
@@ -132,7 +132,7 @@ class Target(SphinxDirective):
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = True
- option_spec = {} # type: Dict
+ option_spec: OptionSpec = {}
def run(self) -> List[Node]:
# normalize whitespace in fullname like XRefRole does
@@ -265,7 +265,7 @@ class Program(SphinxDirective):
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = True
- option_spec = {} # type: Dict
+ option_spec: OptionSpec = {}
def run(self) -> List[Node]:
program = ws_re.sub('-', self.arguments[0].strip())
@@ -329,7 +329,7 @@ class Glossary(SphinxDirective):
required_arguments = 0
optional_arguments = 0
final_argument_whitespace = False
- option_spec = {
+ option_spec: OptionSpec = {
'sorted': directives.flag,
}
@@ -482,7 +482,7 @@ class ProductionList(SphinxDirective):
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = True
- option_spec = {} # type: Dict
+ option_spec: OptionSpec = {}
def run(self) -> List[Node]:
domain = cast(StandardDomain, self.env.get_domain('std'))
diff --git a/sphinx/ext/autodoc/__init__.py b/sphinx/ext/autodoc/__init__.py
index 0b5709301..2abe41234 100644
--- a/sphinx/ext/autodoc/__init__.py
+++ b/sphinx/ext/autodoc/__init__.py
@@ -33,7 +33,7 @@ from sphinx.util import inspect, logging
from sphinx.util.docstrings import extract_metadata, prepare_docstring
from sphinx.util.inspect import (evaluate_signature, getdoc, object_description, safe_getattr,
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
if TYPE_CHECKING:
@@ -309,7 +309,9 @@ class Documenter:
#: true if the generated content may contain titles
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:
"""getattr() override for types such as Zope interfaces."""
@@ -970,7 +972,7 @@ class ModuleDocumenter(Documenter):
content_indent = ''
titles_allowed = True
- option_spec = {
+ option_spec: OptionSpec = {
'members': members_option, 'undoc-members': bool_option,
'noindex': bool_option, 'inherited-members': inherited_members_option,
'show-inheritance': bool_option, 'synopsis': identity,
@@ -978,7 +980,7 @@ class ModuleDocumenter(Documenter):
'member-order': member_order_option, 'exclude-members': exclude_members_option,
'private-members': members_option, 'special-members': members_option,
'imported-members': bool_option, 'ignore-module-all': bool_option
- } # type: Dict[str, Callable]
+ }
def __init__(self, *args: Any) -> None:
super().__init__(*args)
@@ -1419,13 +1421,13 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
"""
objtype = 'class'
member_order = 20
- option_spec = {
+ option_spec: OptionSpec = {
'members': members_option, 'undoc-members': bool_option,
'noindex': bool_option, 'inherited-members': inherited_members_option,
'show-inheritance': bool_option, 'member-order': member_order_option,
'exclude-members': exclude_members_option,
'private-members': members_option, 'special-members': members_option,
- } # type: Dict[str, Callable]
+ }
_signature_class = None # type: Any
_signature_method_name = None # type: str
@@ -1874,7 +1876,7 @@ class DataDocumenter(GenericAliasMixin, NewTypeMixin, TypeVarMixin,
objtype = 'data'
member_order = 40
priority = -10
- option_spec = dict(ModuleLevelDocumenter.option_spec)
+ option_spec: OptionSpec = dict(ModuleLevelDocumenter.option_spec)
option_spec["annotation"] = annotation_option
option_spec["no-value"] = bool_option
@@ -2358,7 +2360,7 @@ class AttributeDocumenter(GenericAliasMixin, NewTypeMixin, SlotsMixin, # type:
"""
objtype = 'attribute'
member_order = 60
- option_spec = dict(ModuleLevelDocumenter.option_spec)
+ option_spec: OptionSpec = dict(ModuleLevelDocumenter.option_spec)
option_spec["annotation"] = annotation_option
option_spec["no-value"] = bool_option
diff --git a/sphinx/ext/autosummary/__init__.py b/sphinx/ext/autosummary/__init__.py
index 1a0fd2409..3cb5bc798 100644
--- a/sphinx/ext/autosummary/__init__.py
+++ b/sphinx/ext/autosummary/__init__.py
@@ -85,6 +85,7 @@ from sphinx.util import logging, rst
from sphinx.util.docutils import (NullReporter, SphinxDirective, SphinxRole, new_document,
switch_source_input)
from sphinx.util.matching import Matcher
+from sphinx.util.typing import OptionSpec
from sphinx.writers.html import HTMLTranslator
logger = logging.getLogger(__name__)
@@ -225,7 +226,7 @@ class Autosummary(SphinxDirective):
optional_arguments = 0
final_argument_whitespace = False
has_content = True
- option_spec = {
+ option_spec: OptionSpec = {
'caption': directives.unchanged_required,
'toctree': directives.unchanged,
'nosignatures': directives.flag,
diff --git a/sphinx/ext/doctest.py b/sphinx/ext/doctest.py
index e48fca248..e7ee8c67d 100644
--- a/sphinx/ext/doctest.py
+++ b/sphinx/ext/doctest.py
@@ -31,6 +31,7 @@ from sphinx.util import logging
from sphinx.util.console import bold # type: ignore
from sphinx.util.docutils import SphinxDirective
from sphinx.util.osutil import relpath
+from sphinx.util.typing import OptionSpec
if TYPE_CHECKING:
from sphinx.application import Sphinx
@@ -150,15 +151,19 @@ class TestDirective(SphinxDirective):
class TestsetupDirective(TestDirective):
- option_spec = {'skipif': directives.unchanged_required} # type: Dict
+ option_spec: OptionSpec = {
+ 'skipif': directives.unchanged_required
+ }
class TestcleanupDirective(TestDirective):
- option_spec = {'skipif': directives.unchanged_required} # type: Dict
+ option_spec: OptionSpec = {
+ 'skipif': directives.unchanged_required
+ }
class DoctestDirective(TestDirective):
- option_spec = {
+ option_spec: OptionSpec = {
'hide': directives.flag,
'no-trim-doctest-flags': directives.flag,
'options': directives.unchanged,
@@ -169,7 +174,7 @@ class DoctestDirective(TestDirective):
class TestcodeDirective(TestDirective):
- option_spec = {
+ option_spec: OptionSpec = {
'hide': directives.flag,
'no-trim-doctest-flags': directives.flag,
'pyversion': directives.unchanged_required,
@@ -179,7 +184,7 @@ class TestcodeDirective(TestDirective):
class TestoutputDirective(TestDirective):
- option_spec = {
+ option_spec: OptionSpec = {
'hide': directives.flag,
'no-trim-doctest-flags': directives.flag,
'options': directives.unchanged,
diff --git a/sphinx/ext/graphviz.py b/sphinx/ext/graphviz.py
index f10285086..f10edfaae 100644
--- a/sphinx/ext/graphviz.py
+++ b/sphinx/ext/graphviz.py
@@ -30,6 +30,7 @@ from sphinx.util.fileutil import copy_asset
from sphinx.util.i18n import search_image_for_language
from sphinx.util.nodes import set_source_info
from sphinx.util.osutil import ensuredir
+from sphinx.util.typing import OptionSpec
from sphinx.writers.html import HTMLTranslator
from sphinx.writers.latex import LaTeXTranslator
from sphinx.writers.manpage import ManualPageTranslator
@@ -113,7 +114,7 @@ class Graphviz(SphinxDirective):
required_arguments = 0
optional_arguments = 1
final_argument_whitespace = False
- option_spec = {
+ option_spec: OptionSpec = {
'alt': directives.unchanged,
'align': align_spec,
'caption': directives.unchanged,
@@ -181,7 +182,7 @@ class GraphvizSimple(SphinxDirective):
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = False
- option_spec = {
+ option_spec: OptionSpec = {
'alt': directives.unchanged,
'align': align_spec,
'caption': directives.unchanged,
diff --git a/sphinx/ext/ifconfig.py b/sphinx/ext/ifconfig.py
index df8545028..0e42984da 100644
--- a/sphinx/ext/ifconfig.py
+++ b/sphinx/ext/ifconfig.py
@@ -28,6 +28,7 @@ import sphinx
from sphinx.application import Sphinx
from sphinx.util.docutils import SphinxDirective
from sphinx.util.nodes import nested_parse_with_titles
+from sphinx.util.typing import OptionSpec
class ifconfig(nodes.Element):
@@ -40,7 +41,7 @@ class IfConfig(SphinxDirective):
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = True
- option_spec = {} # type: Dict
+ option_spec: OptionSpec = {}
def run(self) -> List[Node]:
node = ifconfig()
diff --git a/sphinx/ext/inheritance_diagram.py b/sphinx/ext/inheritance_diagram.py
index 63a171087..62b80ac39 100644
--- a/sphinx/ext/inheritance_diagram.py
+++ b/sphinx/ext/inheritance_diagram.py
@@ -53,6 +53,7 @@ from sphinx.ext.graphviz import (figure_wrapper, graphviz, render_dot_html, rend
render_dot_texinfo)
from sphinx.util import md5
from sphinx.util.docutils import SphinxDirective
+from sphinx.util.typing import OptionSpec
from sphinx.writers.html import HTMLTranslator
from sphinx.writers.latex import LaTeXTranslator
from sphinx.writers.texinfo import TexinfoTranslator
@@ -331,7 +332,7 @@ class InheritanceDiagram(SphinxDirective):
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = True
- option_spec = {
+ option_spec: OptionSpec = {
'parts': int,
'private-bases': directives.flag,
'caption': directives.unchanged,
diff --git a/sphinx/ext/todo.py b/sphinx/ext/todo.py
index e0fdd31e0..e7a2cb51a 100644
--- a/sphinx/ext/todo.py
+++ b/sphinx/ext/todo.py
@@ -27,6 +27,7 @@ from sphinx.errors import NoUri
from sphinx.locale import _, __
from sphinx.util import logging, texescape
from sphinx.util.docutils import SphinxDirective, new_document
+from sphinx.util.typing import OptionSpec
from sphinx.writers.html import HTMLTranslator
from sphinx.writers.latex import LaTeXTranslator
@@ -51,7 +52,7 @@ class Todo(BaseAdmonition, SphinxDirective):
required_arguments = 0
optional_arguments = 0
final_argument_whitespace = False
- option_spec = {
+ option_spec: OptionSpec = {
'class': directives.class_option,
'name': directives.unchanged,
}
@@ -110,7 +111,7 @@ class TodoList(SphinxDirective):
required_arguments = 0
optional_arguments = 0
final_argument_whitespace = False
- option_spec = {} # type: Dict
+ option_spec: OptionSpec = {}
def run(self) -> List[Node]:
# Simply insert an empty todolist node which will be replaced later
diff --git a/sphinx/util/typing.py b/sphinx/util/typing.py
index afd2f805a..128fbd542 100644
--- a/sphinx/util/typing.py
+++ b/sphinx/util/typing.py
@@ -16,6 +16,8 @@ from typing import Any, Callable, Dict, Generator, List, Optional, Tuple, TypeVa
from docutils import nodes
from docutils.parsers.rst.states import Inliner
+from sphinx.deprecation import RemovedInSphinx60Warning, deprecated_alias
+
if sys.version_info > (3, 7):
from typing import ForwardRef
else:
@@ -40,9 +42,6 @@ if False:
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
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]],
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)
TitleGetter = Callable[[nodes.Node], str]
@@ -405,3 +407,10 @@ def _stringify_py36(annotation: Any) -> str:
return 'Union[%s]' % param_str
return qualname
+
+
+deprecated_alias('sphinx.util.typing',
+ {
+ 'DirectiveOption': Callable[[str], Any],
+ },
+ RemovedInSphinx60Warning)