refactor: Use PEP-526 based variable annotation

This commit is contained in:
Takeshi KOMIYA 2020-07-17 01:01:51 +09:00
parent 245b3c32df
commit eb68c237dd
20 changed files with 108 additions and 123 deletions

View File

@ -104,7 +104,7 @@ class toctree(nodes.General, nodes.Element, translatable):
self['caption'] = translated_message self['caption'] = translated_message
def extract_original_messages(self) -> List[str]: def extract_original_messages(self) -> List[str]:
messages = [] # type: List[str] messages: List[str] = []
# toctree entries # toctree entries
messages.extend(self.get('rawentries', [])) messages.extend(self.get('rawentries', []))
@ -209,7 +209,7 @@ class desc_content(nodes.General, nodes.Element):
class desc_sig_element(nodes.inline): class desc_sig_element(nodes.inline):
"""Common parent class of nodes for inline text of a signature.""" """Common parent class of nodes for inline text of a signature."""
classes = [] # type: List[str] classes: List[str] = []
def __init__(self, rawsource: str = '', text: str = '', def __init__(self, rawsource: str = '', text: str = '',
*children: Element, **attributes: Any) -> None: *children: Element, **attributes: Any) -> None:

View File

@ -140,12 +140,12 @@ class Sphinx:
verbosity: int = 0, parallel: int = 0, keep_going: bool = False) -> None: verbosity: int = 0, parallel: int = 0, keep_going: bool = False) -> None:
self.phase = BuildPhase.INITIALIZATION self.phase = BuildPhase.INITIALIZATION
self.verbosity = verbosity self.verbosity = verbosity
self.extensions = {} # type: Dict[str, Extension] self.extensions: Dict[str, Extension] = {}
self.builder = None # type: Builder self.builder: Builder = None
self.env = None # type: BuildEnvironment self.env: BuildEnvironment = None
self.project = None # type: Project self.project: Project = None
self.registry = SphinxComponentRegistry() self.registry = SphinxComponentRegistry()
self.html_themes = {} # type: Dict[str, str] self.html_themes: Dict[str, str] = {}
# validate provided directories # validate provided directories
self.srcdir = abspath(srcdir) self.srcdir = abspath(srcdir)
@ -173,14 +173,14 @@ class Sphinx:
self.parallel = parallel self.parallel = parallel
if status is None: if status is None:
self._status = StringIO() # type: IO self._status: IO = StringIO()
self.quiet = True self.quiet = True
else: else:
self._status = status self._status = status
self.quiet = False self.quiet = False
if warning is None: if warning is None:
self._warning = StringIO() # type: IO self._warning: IO = StringIO()
else: else:
self._warning = warning self._warning = warning
self._warncount = 0 self._warncount = 0
@ -195,7 +195,7 @@ class Sphinx:
# keep last few messages for traceback # keep last few messages for traceback
# This will be filled by sphinx.util.logging.LastMessagesWriter # This will be filled by sphinx.util.logging.LastMessagesWriter
self.messagelog = deque(maxlen=10) # type: deque self.messagelog: deque = deque(maxlen=10)
# say hello to the world # say hello to the world
logger.info(bold(__('Running Sphinx v%s') % sphinx.__display_version__)) logger.info(bold(__('Running Sphinx v%s') % sphinx.__display_version__))
@ -292,7 +292,7 @@ class Sphinx:
if catalog.domain == 'sphinx' and catalog.is_outdated(): if catalog.domain == 'sphinx' and catalog.is_outdated():
catalog.write_mo(self.config.language) catalog.write_mo(self.config.language)
locale_dirs = list(repo.locale_dirs) # type: List[Optional[str]] locale_dirs: List[Optional[str]] = list(repo.locale_dirs)
locale_dirs += [None] locale_dirs += [None]
locale_dirs += [path.join(package_dir, 'locale')] locale_dirs += [path.join(package_dir, 'locale')]

View File

@ -53,8 +53,8 @@ class TexinfoBuilder(Builder):
default_translator_class = TexinfoTranslator default_translator_class = TexinfoTranslator
def init(self) -> None: def init(self) -> None:
self.docnames = [] # type: Iterable[str] self.docnames: Iterable[str] = []
self.document_data = [] # type: List[Tuple[str, str, str, str, str, str, str, bool]] self.document_data: List[Tuple[str, str, str, str, str, str, str, bool]] = []
def get_outdated_docs(self) -> Union[str, List[str]]: def get_outdated_docs(self) -> Union[str, List[str]]:
return 'all documents' # for now return 'all documents' # for now
@ -76,7 +76,7 @@ class TexinfoBuilder(Builder):
'will be written')) 'will be written'))
return return
# assign subdirs to titles # assign subdirs to titles
self.titles = [] # type: List[Tuple[str, str]] self.titles: List[Tuple[str, str]] = []
for entry in preliminary_document_data: for entry in preliminary_document_data:
docname = entry[0] docname = entry[0]
if docname not in self.env.all_docs: if docname not in self.env.all_docs:
@ -109,10 +109,10 @@ class TexinfoBuilder(Builder):
with progress_message(__("writing")): with progress_message(__("writing")):
self.post_process_images(doctree) self.post_process_images(doctree)
docwriter = TexinfoWriter(self) docwriter = TexinfoWriter(self)
settings = OptionParser( settings: Any = OptionParser(
defaults=self.env.settings, defaults=self.env.settings,
components=(docwriter,), components=(docwriter,),
read_config_files=True).get_default_values() # type: Any read_config_files=True).get_default_values()
settings.author = author settings.author = author
settings.title = title settings.title = title
settings.texinfo_filename = targetname[:-5] + '.info' settings.texinfo_filename = targetname[:-5] + '.info'

View File

@ -14,7 +14,7 @@ import types
from collections import OrderedDict from collections import OrderedDict
from os import getenv, path from os import getenv, path
from typing import (TYPE_CHECKING, Any, Callable, Dict, Generator, Iterator, List, NamedTuple, from typing import (TYPE_CHECKING, Any, Callable, Dict, Generator, Iterator, List, NamedTuple,
Set, Tuple, Union) Optional, Set, Tuple, Union)
from sphinx.errors import ConfigError, ExtensionError from sphinx.errors import ConfigError, ExtensionError
from sphinx.locale import _, __ from sphinx.locale import _, __
@ -88,7 +88,7 @@ class Config:
# If you add a value here, don't forget to include it in the # If you add a value here, don't forget to include it in the
# quickstart.py file template as well as in the docs! # quickstart.py file template as well as in the docs!
config_values = { config_values: Dict[str, Tuple] = {
# general options # general options
'project': ('Python', 'env', []), 'project': ('Python', 'env', []),
'author': ('unknown', 'env', []), 'author': ('unknown', 'env', []),
@ -146,20 +146,20 @@ class Config:
'smartquotes_excludes': ({'languages': ['ja'], 'smartquotes_excludes': ({'languages': ['ja'],
'builders': ['man', 'text']}, 'builders': ['man', 'text']},
'env', []), 'env', []),
} # type: Dict[str, Tuple] }
def __init__(self, config: Dict[str, Any] = {}, overrides: Dict[str, Any] = {}) -> None: def __init__(self, config: Dict[str, Any] = {}, overrides: Dict[str, Any] = {}) -> None:
self.overrides = dict(overrides) self.overrides = dict(overrides)
self.values = Config.config_values.copy() self.values = Config.config_values.copy()
self._raw_config = config self._raw_config = config
self.setup = config.get('setup', None) # type: Callable self.setup: Optional[Callable] = config.get('setup', None)
if 'extensions' in self.overrides: if 'extensions' in self.overrides:
if isinstance(self.overrides['extensions'], str): if isinstance(self.overrides['extensions'], str):
config['extensions'] = self.overrides.pop('extensions').split(',') config['extensions'] = self.overrides.pop('extensions').split(',')
else: else:
config['extensions'] = self.overrides.pop('extensions') config['extensions'] = self.overrides.pop('extensions')
self.extensions = config.get('extensions', []) # type: List[str] self.extensions: List[str] = config.get('extensions', [])
@classmethod @classmethod
def read(cls, confdir: str, overrides: Dict = None, tags: Tags = None) -> "Config": def read(cls, confdir: str, overrides: Dict = None, tags: Tags = None) -> "Config":
@ -311,7 +311,7 @@ class Config:
def eval_config_file(filename: str, tags: Tags) -> Dict[str, Any]: def eval_config_file(filename: str, tags: Tags) -> Dict[str, Any]:
"""Evaluate a config file.""" """Evaluate a config file."""
namespace = {} # type: Dict[str, Any] namespace: Dict[str, Any] = {}
namespace['__file__'] = filename namespace['__file__'] = filename
namespace['tags'] = tags namespace['tags'] = tags

View File

@ -58,7 +58,7 @@ class EventManager:
def __init__(self, app: "Sphinx") -> None: def __init__(self, app: "Sphinx") -> None:
self.app = app self.app = app
self.events = core_events.copy() self.events = core_events.copy()
self.listeners = defaultdict(list) # type: Dict[str, List[EventListener]] self.listeners: Dict[str, List[EventListener]] = defaultdict(list)
self.next_listener_id = 0 self.next_listener_id = 0
def add(self, name: str) -> None: def add(self, name: str) -> None:

View File

@ -60,7 +60,7 @@ import sys
import warnings import warnings
from os import path from os import path
from types import ModuleType from types import ModuleType
from typing import Any, Dict, List, Tuple, Type, cast from typing import Any, Dict, List, Optional, Tuple, Type, cast
from docutils import nodes from docutils import nodes
from docutils.nodes import Element, Node, system_message from docutils.nodes import Element, Node, system_message
@ -165,7 +165,7 @@ def autosummary_table_visit_html(self: HTMLTranslator, node: autosummary_table)
# -- autodoc integration ------------------------------------------------------- # -- autodoc integration -------------------------------------------------------
# current application object (used in `get_documenter()`). # current application object (used in `get_documenter()`).
_app = None # type: Sphinx _app: Sphinx = None
class FakeDirective(DocumenterBridge): class FakeDirective(DocumenterBridge):
@ -311,7 +311,7 @@ class Autosummary(SphinxDirective):
""" """
prefixes = get_import_prefixes_from_env(self.env) prefixes = get_import_prefixes_from_env(self.env)
items = [] # type: List[Tuple[str, str, str, str]] items: List[Tuple[str, str, str, str]] = []
max_item_chars = 50 max_item_chars = 50
@ -461,8 +461,8 @@ def mangle_signature(sig: str, max_chars: int = 30) -> str:
s = re.sub(r'{[^}]*}', '', s) s = re.sub(r'{[^}]*}', '', s)
# Parse the signature to arguments + options # Parse the signature to arguments + options
args = [] # type: List[str] args: List[str] = []
opts = [] # type: List[str] opts: List[str] = []
opt_re = re.compile(r"^(.*, |)([a-zA-Z0-9_*]+)\s*=\s*") opt_re = re.compile(r"^(.*, |)([a-zA-Z0-9_*]+)\s*=\s*")
while s: while s:
@ -579,7 +579,7 @@ def get_import_prefixes_from_env(env: BuildEnvironment) -> List[str]:
Obtain current Python import prefixes (for `import_by_name`) Obtain current Python import prefixes (for `import_by_name`)
from ``document.env`` from ``document.env``
""" """
prefixes = [None] # type: List[str] prefixes: List[Optional[str]] = [None]
currmodule = env.ref_context.get('py:module') currmodule = env.ref_context.get('py:module')
if currmodule: if currmodule:
@ -707,7 +707,7 @@ def get_rst_suffix(app: Sphinx) -> str:
return ('restructuredtext',) return ('restructuredtext',)
return parser_class.supported return parser_class.supported
suffix = None # type: str suffix: str = None
for suffix in app.config.source_suffix: for suffix in app.config.source_suffix:
if 'restructuredtext' in get_supported_format(suffix): if 'restructuredtext' in get_supported_format(suffix):
return suffix return suffix

View File

@ -87,11 +87,11 @@ def setup_documenters(app: Any) -> None:
FunctionDocumenter, MethodDocumenter, ModuleDocumenter, FunctionDocumenter, MethodDocumenter, ModuleDocumenter,
NewTypeAttributeDocumenter, NewTypeDataDocumenter, NewTypeAttributeDocumenter, NewTypeDataDocumenter,
PropertyDocumenter) PropertyDocumenter)
documenters = [ documenters: List[Type[Documenter]] = [
ModuleDocumenter, ClassDocumenter, ExceptionDocumenter, DataDocumenter, ModuleDocumenter, ClassDocumenter, ExceptionDocumenter, DataDocumenter,
FunctionDocumenter, MethodDocumenter, NewTypeAttributeDocumenter, FunctionDocumenter, MethodDocumenter, NewTypeAttributeDocumenter,
NewTypeDataDocumenter, AttributeDocumenter, DecoratorDocumenter, PropertyDocumenter, NewTypeDataDocumenter, AttributeDocumenter, DecoratorDocumenter, PropertyDocumenter,
] # type: List[Type[Documenter]] ]
for documenter in documenters: for documenter in documenters:
app.registry.add_documenter(documenter.objtype, documenter) app.registry.add_documenter(documenter.objtype, documenter)
@ -241,8 +241,8 @@ def generate_autosummary_content(name: str, obj: Any, parent: Any,
def get_members(obj: Any, types: Set[str], include_public: List[str] = [], def get_members(obj: Any, types: Set[str], include_public: List[str] = [],
imported: bool = True) -> Tuple[List[str], List[str]]: imported: bool = True) -> Tuple[List[str], List[str]]:
items = [] # type: List[str] items: List[str] = []
public = [] # type: List[str] public: List[str] = []
for name in dir(obj): for name in dir(obj):
try: try:
value = safe_getattr(obj, name) value = safe_getattr(obj, name)
@ -282,7 +282,7 @@ def generate_autosummary_content(name: str, obj: Any, parent: Any,
return public, attrs return public, attrs
def get_modules(obj: Any) -> Tuple[List[str], List[str]]: def get_modules(obj: Any) -> Tuple[List[str], List[str]]:
items = [] # type: List[str] items: List[str] = []
for _, modname, ispkg in pkgutil.iter_modules(obj.__path__): for _, modname, ispkg in pkgutil.iter_modules(obj.__path__):
fullname = name + '.' + modname fullname = name + '.' + modname
try: try:
@ -296,7 +296,7 @@ def generate_autosummary_content(name: str, obj: Any, parent: Any,
public = [x for x in items if not x.split('.')[-1].startswith('_')] public = [x for x in items if not x.split('.')[-1].startswith('_')]
return public, items return public, items
ns = {} # type: Dict[str, Any] ns: Dict[str, Any] = {}
ns.update(context) ns.update(context)
if doc.objtype == 'module': if doc.objtype == 'module':
@ -447,7 +447,7 @@ def find_autosummary_in_files(filenames: List[str]) -> List[AutosummaryEntry]:
See `find_autosummary_in_lines`. See `find_autosummary_in_lines`.
""" """
documented = [] # type: List[AutosummaryEntry] documented: List[AutosummaryEntry] = []
for filename in filenames: for filename in filenames:
with open(filename, encoding='utf-8', errors='ignore') as f: with open(filename, encoding='utf-8', errors='ignore') as f:
lines = f.read().splitlines() lines = f.read().splitlines()
@ -501,10 +501,10 @@ def find_autosummary_in_lines(lines: List[str], module: str = None, filename: st
toctree_arg_re = re.compile(r'^\s+:toctree:\s*(.*?)\s*$') toctree_arg_re = re.compile(r'^\s+:toctree:\s*(.*?)\s*$')
template_arg_re = re.compile(r'^\s+:template:\s*(.*?)\s*$') template_arg_re = re.compile(r'^\s+:template:\s*(.*?)\s*$')
documented = [] # type: List[AutosummaryEntry] documented: List[AutosummaryEntry] = []
recursive = False recursive = False
toctree = None # type: str toctree: str = None
template = None template = None
current_module = module current_module = module
in_autosummary = False in_autosummary = False

View File

@ -87,7 +87,7 @@ class TestDirective(SphinxDirective):
if not test: if not test:
test = code test = code
code = doctestopt_re.sub('', code) code = doctestopt_re.sub('', code)
nodetype = nodes.literal_block # type: Type[TextElement] nodetype: Type[TextElement] = nodes.literal_block
if self.name in ('testsetup', 'testcleanup') or 'hide' in self.options: if self.name in ('testsetup', 'testcleanup') or 'hide' in self.options:
nodetype = nodes.comment nodetype = nodes.comment
if self.arguments: if self.arguments:
@ -202,9 +202,9 @@ parser = doctest.DocTestParser()
class TestGroup: class TestGroup:
def __init__(self, name: str) -> None: def __init__(self, name: str) -> None:
self.name = name self.name = name
self.setup = [] # type: List[TestCode] self.setup: List[TestCode] = []
self.tests = [] # type: List[List[TestCode]] self.tests: List[List[TestCode]] = []
self.cleanup = [] # type: List[TestCode] self.cleanup: List[TestCode] = []
def add_code(self, code: "TestCode", prepend: bool = False) -> None: def add_code(self, code: "TestCode", prepend: bool = False) -> None:
if code.type == 'testsetup': if code.type == 'testsetup':
@ -392,7 +392,7 @@ Doctest summary
return False return False
else: else:
condition = node['skipif'] condition = node['skipif']
context = {} # type: Dict[str, Any] context: Dict[str, Any] = {}
if self.config.doctest_global_setup: if self.config.doctest_global_setup:
exec(self.config.doctest_global_setup, context) exec(self.config.doctest_global_setup, context)
should_skip = eval(condition, context) should_skip = eval(condition, context)
@ -401,7 +401,7 @@ Doctest summary
return should_skip return should_skip
def test_doc(self, docname: str, doctree: Node) -> None: def test_doc(self, docname: str, doctree: Node) -> None:
groups = {} # type: Dict[str, TestGroup] groups: Dict[str, TestGroup] = {}
add_to_all_groups = [] add_to_all_groups = []
self.setup_runner = SphinxDocTestRunner(verbose=False, self.setup_runner = SphinxDocTestRunner(verbose=False,
optionflags=self.opt) optionflags=self.opt)
@ -482,7 +482,7 @@ Doctest summary
return compile(code, name, self.type, flags, dont_inherit) return compile(code, name, self.type, flags, dont_inherit)
def test_group(self, group: TestGroup) -> None: def test_group(self, group: TestGroup) -> None:
ns = {} # type: Dict ns: Dict = {}
def run_setup_cleanup(runner: Any, testcodes: List[TestCode], what: Any) -> bool: def run_setup_cleanup(runner: Any, testcodes: List[TestCode], what: Any) -> bool:
examples = [] examples = []

View File

@ -130,14 +130,14 @@ class TodoListProcessor:
self.process(doctree, docname) self.process(doctree, docname)
def process(self, doctree: nodes.document, docname: str) -> None: def process(self, doctree: nodes.document, docname: str) -> None:
todos = sum(self.domain.todos.values(), []) # type: List[todo_node] todos: List[todo_node] = sum(self.domain.todos.values(), [])
for node in doctree.traverse(todolist): for node in doctree.traverse(todolist):
if not self.config.todo_include_todos: if not self.config.todo_include_todos:
node.parent.remove(node) node.parent.remove(node)
continue continue
if node.get('ids'): if node.get('ids'):
content = [nodes.target()] # type: List[Element] content: List[Element] = [nodes.target()]
else: else:
content = [] content = []

View File

@ -111,7 +111,7 @@ def doctree_read(app: Sphinx, doctree: Node) -> None:
for objnode in doctree.traverse(addnodes.desc): for objnode in doctree.traverse(addnodes.desc):
if objnode.get('domain') != 'py': if objnode.get('domain') != 'py':
continue continue
names = set() # type: Set[str] names: Set[str] = set()
for signode in objnode: for signode in objnode:
if not isinstance(signode, addnodes.desc_signature): if not isinstance(signode, addnodes.desc_signature):
continue continue

View File

@ -31,8 +31,8 @@ from sphinx.util import logging, texescape
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
lexers = {} # type: Dict[str, Lexer] lexers: Dict[str, Lexer] = {}
lexer_classes = { lexer_classes: Dict[str, Lexer] = {
'none': partial(TextLexer, stripnl=False), 'none': partial(TextLexer, stripnl=False),
'python': partial(PythonLexer, stripnl=False), 'python': partial(PythonLexer, stripnl=False),
'python3': partial(Python3Lexer, stripnl=False), 'python3': partial(Python3Lexer, stripnl=False),
@ -40,7 +40,7 @@ lexer_classes = {
'pycon3': partial(PythonConsoleLexer, python3=True, stripnl=False), 'pycon3': partial(PythonConsoleLexer, python3=True, stripnl=False),
'rest': partial(RstLexer, stripnl=False), 'rest': partial(RstLexer, stripnl=False),
'c': partial(CLexer, stripnl=False), 'c': partial(CLexer, stripnl=False),
} # type: Dict[str, Lexer] }
escape_hl_chars = {ord('\\'): '\\PYGZbs{}', escape_hl_chars = {ord('\\'): '\\PYGZbs{}',
@ -80,7 +80,7 @@ class PygmentsBridge:
self.latex_engine = latex_engine self.latex_engine = latex_engine
style = self.get_style(stylename) style = self.get_style(stylename)
self.formatter_args = {'style': style} # type: Dict[str, Any] self.formatter_args: Dict[str, Any] = {'style': style}
if dest == 'html': if dest == 'html':
self.formatter = self.html_formatter self.formatter = self.html_formatter
else: else:

View File

@ -46,7 +46,7 @@ class SphinxBaseReader(standalone.Reader):
This replaces reporter by Sphinx's on generating document. This replaces reporter by Sphinx's on generating document.
""" """
transforms = [] # type: List[Type[Transform]] transforms: List[Type[Transform]] = []
def __init__(self, *args: Any, **kwargs: Any) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None:
from sphinx.application import Sphinx from sphinx.application import Sphinx

View File

@ -103,7 +103,7 @@ class _TranslationProxy(UserString):
return '<%s broken>' % self.__class__.__name__ return '<%s broken>' % self.__class__.__name__
translators = defaultdict(NullTranslations) # type: Dict[Tuple[str, str], NullTranslations] translators: Dict[Tuple[str, str], NullTranslations] = defaultdict(NullTranslations)
def init(locale_dirs: List[Optional[str]], language: Optional[str], def init(locale_dirs: List[Optional[str]], language: Optional[str],
@ -123,7 +123,7 @@ def init(locale_dirs: List[Optional[str]], language: Optional[str],
if language and '_' in language: if language and '_' in language:
# for language having country code (like "de_AT") # for language having country code (like "de_AT")
languages = [language, language.split('_')[0]] # type: Optional[List[str]] languages: Optional[List[str]] = [language, language.split('_')[0]]
elif language: elif language:
languages = [language] languages = [language]
else: else:
@ -262,7 +262,7 @@ admonitionlabels = {
} }
# Moved to sphinx.directives.other (will be overriden later) # Moved to sphinx.directives.other (will be overriden later)
versionlabels = {} # type: Dict[str, str] versionlabels: Dict[str, str] = {}
# Moved to sphinx.domains.python (will be overriden later) # Moved to sphinx.domains.python (will be overriden later)
pairindextypes = {} # type: Dict[str, str] pairindextypes: Dict[str, str] = {}

View File

@ -10,17 +10,13 @@
import os import os
from glob import glob from glob import glob
from typing import TYPE_CHECKING from typing import Dict, List, Set
from sphinx.locale import __ from sphinx.locale import __
from sphinx.util import get_matching_files, logging, path_stabilize from sphinx.util import get_matching_files, logging, path_stabilize
from sphinx.util.matching import compile_matchers from sphinx.util.matching import compile_matchers
from sphinx.util.osutil import SEP, relpath from sphinx.util.osutil import SEP, relpath
if TYPE_CHECKING:
from typing import Dict, List, Set
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
EXCLUDE_PATHS = ['**/_sources', '.#*', '**/.#*', '*.lproj/**'] EXCLUDE_PATHS = ['**/_sources', '.#*', '**/.#*', '*.lproj/**']
@ -28,8 +24,7 @@ EXCLUDE_PATHS = ['**/_sources', '.#*', '**/.#*', '*.lproj/**']
class Project: class Project:
"""A project is source code set of Sphinx document.""" """A project is source code set of Sphinx document."""
def __init__(self, srcdir, source_suffix): def __init__(self, srcdir: str, source_suffix: Dict[str, str]) -> None:
# type: (str, Dict[str, str]) -> None
#: Source directory. #: Source directory.
self.srcdir = srcdir self.srcdir = srcdir
@ -37,15 +32,13 @@ class Project:
self.source_suffix = source_suffix self.source_suffix = source_suffix
#: The name of documents belongs to this project. #: The name of documents belongs to this project.
self.docnames = set() # type: Set[str] self.docnames: Set[str] = set()
def restore(self, other): def restore(self, other: "Project") -> None:
# type: (Project) -> None
"""Take over a result of last build.""" """Take over a result of last build."""
self.docnames = other.docnames self.docnames = other.docnames
def discover(self, exclude_paths=[]): def discover(self, exclude_paths: List[str] = []) -> Set[str]:
# type: (List[str]) -> Set[str]
"""Find all document files in the source directory and put them in """Find all document files in the source directory and put them in
:attr:`docnames`. :attr:`docnames`.
""" """
@ -67,8 +60,7 @@ class Project:
return self.docnames return self.docnames
def path2doc(self, filename): def path2doc(self, filename: str) -> str:
# type: (str) -> str
"""Return the docname for the filename if the file is document. """Return the docname for the filename if the file is document.
*filename* should be absolute or relative to the source directory. *filename* should be absolute or relative to the source directory.
@ -83,8 +75,7 @@ class Project:
# the file does not have docname # the file does not have docname
return None return None
def doc2path(self, docname, basedir=True): def doc2path(self, docname: str, basedir: bool = True) -> str:
# type: (str, bool) -> str
"""Return the filename for the document name. """Return the filename for the document name.
If *basedir* is True, return as an absolute path. If *basedir* is True, return as an absolute path.

View File

@ -53,74 +53,74 @@ EXTENSION_BLACKLIST = {
class SphinxComponentRegistry: class SphinxComponentRegistry:
def __init__(self) -> None: def __init__(self) -> None:
#: special attrgetter for autodoc; class object -> attrgetter #: special attrgetter for autodoc; class object -> attrgetter
self.autodoc_attrgettrs = {} # type: Dict[Type, Callable[[Any, str, Any], Any]] self.autodoc_attrgettrs: Dict[Type, Callable[[Any, str, Any], Any]] = {}
#: builders; a dict of builder name -> bulider class #: builders; a dict of builder name -> bulider class
self.builders = {} # type: Dict[str, Type[Builder]] self.builders: Dict[str, Type[Builder]] = {}
#: autodoc documenters; a dict of documenter name -> documenter class #: autodoc documenters; a dict of documenter name -> documenter class
self.documenters = {} # type: Dict[str, Type[Documenter]] self.documenters: Dict[str, Type[Documenter]] = {}
#: css_files; a list of tuple of filename and attributes #: css_files; a list of tuple of filename and attributes
self.css_files = [] # type: List[Tuple[str, Dict[str, Any]]] self.css_files: List[Tuple[str, Dict[str, Any]]] = []
#: domains; a dict of domain name -> domain class #: domains; a dict of domain name -> domain class
self.domains = {} # type: Dict[str, Type[Domain]] self.domains: Dict[str, Type[Domain]] = {}
#: additional directives for domains #: additional directives for domains
#: a dict of domain name -> dict of directive name -> directive #: a dict of domain name -> dict of directive name -> directive
self.domain_directives = {} # type: Dict[str, Dict[str, Any]] self.domain_directives: Dict[str, Dict[str, Any]] = {}
#: additional indices for domains #: additional indices for domains
#: a dict of domain name -> list of index class #: a dict of domain name -> list of index class
self.domain_indices = {} # type: Dict[str, List[Type[Index]]] self.domain_indices: Dict[str, List[Type[Index]]] = {}
#: additional object types for domains #: additional object types for domains
#: a dict of domain name -> dict of objtype name -> objtype #: a dict of domain name -> dict of objtype name -> objtype
self.domain_object_types = {} # type: Dict[str, Dict[str, ObjType]] self.domain_object_types: Dict[str, Dict[str, ObjType]] = {}
#: additional roles for domains #: additional roles for domains
#: a dict of domain name -> dict of role name -> role impl. #: a dict of domain name -> dict of role name -> role impl.
self.domain_roles = {} # type: Dict[str, Dict[str, Union[RoleFunction, XRefRole]]] # NOQA self.domain_roles: Dict[str, Dict[str, Union[RoleFunction, XRefRole]]] = {}
#: additional enumerable nodes #: additional enumerable nodes
#: a dict of node class -> tuple of figtype and title_getter function #: a dict of node class -> tuple of figtype and title_getter function
self.enumerable_nodes = {} # type: Dict[Type[Node], Tuple[str, TitleGetter]] self.enumerable_nodes: Dict[Type[Node], Tuple[str, TitleGetter]] = {}
#: HTML inline and block math renderers #: HTML inline and block math renderers
#: a dict of name -> tuple of visit function and depart function #: a dict of name -> tuple of visit function and depart function
self.html_inline_math_renderers = {} # type: Dict[str, Tuple[Callable, Callable]] self.html_inline_math_renderers: Dict[str, Tuple[Callable, Callable]] = {}
self.html_block_math_renderers = {} # type: Dict[str, Tuple[Callable, Callable]] self.html_block_math_renderers: Dict[str, Tuple[Callable, Callable]] = {}
#: js_files; list of JS paths or URLs #: js_files; list of JS paths or URLs
self.js_files = [] # type: List[Tuple[str, Dict[str, Any]]] self.js_files: List[Tuple[str, Dict[str, Any]]] = []
#: LaTeX packages; list of package names and its options #: LaTeX packages; list of package names and its options
self.latex_packages = [] # type: List[Tuple[str, str]] self.latex_packages: List[Tuple[str, str]] = []
self.latex_packages_after_hyperref = [] # type: List[Tuple[str, str]] self.latex_packages_after_hyperref: List[Tuple[str, str]] = []
#: post transforms; list of transforms #: post transforms; list of transforms
self.post_transforms = [] # type: List[Type[Transform]] self.post_transforms: List[Type[Transform]] = []
#: source paresrs; file type -> parser class #: source paresrs; file type -> parser class
self.source_parsers = {} # type: Dict[str, Type[Parser]] self.source_parsers: Dict[str, Type[Parser]] = {}
#: source inputs; file type -> input class #: source inputs; file type -> input class
self.source_inputs = {} # type: Dict[str, Type[Input]] self.source_inputs: Dict[str, Type[Input]] = {}
#: source suffix: suffix -> file type #: source suffix: suffix -> file type
self.source_suffix = {} # type: Dict[str, str] self.source_suffix: Dict[str, str] = {}
#: custom translators; builder name -> translator class #: custom translators; builder name -> translator class
self.translators = {} # type: Dict[str, Type[nodes.NodeVisitor]] self.translators: Dict[str, Type[nodes.NodeVisitor]] = {}
#: custom handlers for translators #: custom handlers for translators
#: a dict of builder name -> dict of node name -> visitor and departure functions #: a dict of builder name -> dict of node name -> visitor and departure functions
self.translation_handlers = {} # type: Dict[str, Dict[str, Tuple[Callable, Callable]]] self.translation_handlers: Dict[str, Dict[str, Tuple[Callable, Callable]]] = {}
#: additional transforms; list of transforms #: additional transforms; list of transforms
self.transforms = [] # type: List[Type[Transform]] self.transforms: List[Type[Transform]] = []
def add_builder(self, builder: Type[Builder], override: bool = False) -> None: def add_builder(self, builder: Type[Builder], override: bool = False) -> None:
logger.debug('[app] adding builder: %r', builder) logger.debug('[app] adding builder: %r', builder)
@ -426,7 +426,7 @@ class SphinxComponentRegistry:
if setup is None: if setup is None:
logger.warning(__('extension %r has no setup() function; is it really ' logger.warning(__('extension %r has no setup() function; is it really '
'a Sphinx extension module?'), extname) 'a Sphinx extension module?'), extname)
metadata = {} # type: Dict[str, Any] metadata: Dict[str, Any] = {}
else: else:
try: try:
metadata = setup(app) metadata = setup(app)

View File

@ -65,8 +65,8 @@ class XRefRole(ReferenceRole):
* Subclassing and overwriting `process_link()` and/or `result_nodes()`. * Subclassing and overwriting `process_link()` and/or `result_nodes()`.
""" """
nodeclass = addnodes.pending_xref # type: Type[Element] nodeclass: Type[Element] = addnodes.pending_xref
innernodeclass = nodes.literal # type: Type[TextElement] innernodeclass: Type[TextElement] = nodes.literal
def __init__(self, fix_parens: bool = False, lowercase: bool = False, def __init__(self, fix_parens: bool = False, lowercase: bool = False,
nodeclass: Type[Element] = None, innernodeclass: Type[TextElement] = None, nodeclass: Type[Element] = None, innernodeclass: Type[TextElement] = None,
@ -284,7 +284,7 @@ class EmphasizedLiteral(SphinxRole):
return [node], [] return [node], []
def parse(self, text: str) -> List[Node]: def parse(self, text: str) -> List[Node]:
result = [] # type: List[Node] result: List[Node] = []
stack = [''] stack = ['']
for part in self.parens_re.split(text): for part in self.parens_re.split(text):
@ -341,7 +341,7 @@ class Abbreviation(SphinxRole):
return [nodes.abbreviation(self.rawtext, text, **options)], [] return [nodes.abbreviation(self.rawtext, text, **options)], []
specific_docroles = { specific_docroles: Dict[str, RoleFunction] = {
# links to download references # links to download references
'download': XRefRole(nodeclass=addnodes.download_reference), 'download': XRefRole(nodeclass=addnodes.download_reference),
# links to anything # links to anything
@ -354,7 +354,7 @@ specific_docroles = {
'file': EmphasizedLiteral(), 'file': EmphasizedLiteral(),
'samp': EmphasizedLiteral(), 'samp': EmphasizedLiteral(),
'abbr': Abbreviation(), 'abbr': Abbreviation(),
} # type: Dict[str, RoleFunction] }
def setup(app: "Sphinx") -> Dict[str, Any]: def setup(app: "Sphinx") -> Dict[str, Any]:

View File

@ -16,7 +16,7 @@ import sys
from distutils.cmd import Command from distutils.cmd import Command
from distutils.errors import DistutilsExecError from distutils.errors import DistutilsExecError
from io import StringIO from io import StringIO
from typing import TYPE_CHECKING from typing import Any, Dict
from sphinx.application import Sphinx from sphinx.application import Sphinx
from sphinx.cmd.build import handle_exception from sphinx.cmd.build import handle_exception
@ -24,9 +24,6 @@ from sphinx.util.console import color_terminal, nocolor
from sphinx.util.docutils import docutils_namespace, patch_docutils from sphinx.util.docutils import docutils_namespace, patch_docutils
from sphinx.util.osutil import abspath from sphinx.util.osutil import abspath
if TYPE_CHECKING:
from typing import Any, Dict
class BuildDoc(Command): class BuildDoc(Command):
""" """
@ -91,18 +88,18 @@ class BuildDoc(Command):
boolean_options = ['fresh-env', 'all-files', 'warning-is-error', boolean_options = ['fresh-env', 'all-files', 'warning-is-error',
'link-index', 'nitpicky'] 'link-index', 'nitpicky']
def initialize_options(self): def initialize_options(self) -> None:
# type: () -> None
self.fresh_env = self.all_files = False self.fresh_env = self.all_files = False
self.pdb = False self.pdb = False
self.source_dir = self.build_dir = None # type: str self.source_dir: str = None
self.build_dir: str = None
self.builder = 'html' self.builder = 'html'
self.warning_is_error = False self.warning_is_error = False
self.project = '' self.project = ''
self.version = '' self.version = ''
self.release = '' self.release = ''
self.today = '' self.today = ''
self.config_dir = None # type: str self.config_dir: str = None
self.link_index = False self.link_index = False
self.copyright = '' self.copyright = ''
# Link verbosity to distutils' (which uses 1 by default). # Link verbosity to distutils' (which uses 1 by default).
@ -111,8 +108,7 @@ class BuildDoc(Command):
self.nitpicky = False self.nitpicky = False
self.keep_going = False self.keep_going = False
def _guess_source_dir(self): def _guess_source_dir(self) -> str:
# type: () -> str
for guess in ('doc', 'docs'): for guess in ('doc', 'docs'):
if not os.path.isdir(guess): if not os.path.isdir(guess):
continue continue
@ -121,8 +117,7 @@ class BuildDoc(Command):
return root return root
return os.curdir return os.curdir
def finalize_options(self): def finalize_options(self) -> None:
# type: () -> None
self.ensure_string_list('builder') self.ensure_string_list('builder')
if self.source_dir is None: if self.source_dir is None:
@ -144,15 +139,14 @@ class BuildDoc(Command):
(builder, os.path.join(self.build_dir, builder)) (builder, os.path.join(self.build_dir, builder))
for builder in self.builder] for builder in self.builder]
def run(self): def run(self) -> None:
# type: () -> None
if not color_terminal(): if not color_terminal():
nocolor() nocolor()
if not self.verbose: # type: ignore if not self.verbose: # type: ignore
status_stream = StringIO() status_stream = StringIO()
else: else:
status_stream = sys.stdout # type: ignore status_stream = sys.stdout # type: ignore
confoverrides = {} # type: Dict[str, Any] confoverrides: Dict[str, Any] = {}
if self.project: if self.project:
confoverrides['project'] = self.project confoverrides['project'] = self.project
if self.version: if self.version:

View File

@ -41,7 +41,7 @@ def rootdir() -> str:
class SharedResult: class SharedResult:
cache = {} # type: Dict[str, Dict[str, str]] cache: Dict[str, Dict[str, str]] = {}
def store(self, key: str, app_: SphinxTestApp) -> Any: def store(self, key: str, app_: SphinxTestApp) -> Any:
if key in self.cache: if key in self.cache:
@ -77,7 +77,7 @@ def app_params(request: Any, test_params: Dict, shared_result: SharedResult,
else: else:
markers = request.node.get_marker("sphinx") markers = request.node.get_marker("sphinx")
pargs = {} pargs = {}
kwargs = {} # type: Dict[str, Any] kwargs: Dict[str, Any] = {}
if markers is not None: if markers is not None:
# to avoid stacking positional args # to avoid stacking positional args
@ -190,7 +190,7 @@ def make_app(test_params: Dict, monkeypatch: Any) -> Generator[Callable, None, N
status, warning = StringIO(), StringIO() status, warning = StringIO(), StringIO()
kwargs.setdefault('status', status) kwargs.setdefault('status', status)
kwargs.setdefault('warning', warning) kwargs.setdefault('warning', warning)
app_ = SphinxTestApp(*args, **kwargs) # type: Any app_: Any = SphinxTestApp(*args, **kwargs)
apps.append(app_) apps.append(app_)
if test_params['shared_result']: if test_params['shared_result']:
app_ = SphinxTestAppWrapperForSkipBuilding(app_) app_ = SphinxTestAppWrapperForSkipBuilding(app_)

View File

@ -99,8 +99,8 @@ class SphinxTestApp(application.Sphinx):
A subclass of :class:`Sphinx` that runs on the test root, with some A subclass of :class:`Sphinx` that runs on the test root, with some
better default values for the initialization parameters. better default values for the initialization parameters.
""" """
_status = None # type: StringIO _status: StringIO = None
_warning = None # type: StringIO _warning: StringIO = None
def __init__(self, buildername: str = 'html', srcdir: path = None, freshenv: bool = False, def __init__(self, buildername: str = 'html', srcdir: path = None, freshenv: bool = False,
confoverrides: Dict = None, status: IO = None, warning: IO = None, confoverrides: Dict = None, status: IO = None, warning: IO = None,

View File

@ -211,7 +211,7 @@ class HTMLThemeFactory:
def find_themes(self, theme_path: str) -> Dict[str, str]: def find_themes(self, theme_path: str) -> Dict[str, str]:
"""Search themes from specified directory.""" """Search themes from specified directory."""
themes = {} # type: Dict[str, str] themes: Dict[str, str] = {}
if not path.isdir(theme_path): if not path.isdir(theme_path):
return themes return themes