refactor: Use PEP-526 based variable annotation (sphinx.environment)

This commit is contained in:
Takeshi KOMIYA 2021-03-25 00:09:21 +09:00
parent 6e4df0a419
commit 000ae2e500
6 changed files with 78 additions and 81 deletions

View File

@ -42,7 +42,7 @@ if TYPE_CHECKING:
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
default_settings = { default_settings: Dict[str, Any] = {
'embed_stylesheet': False, 'embed_stylesheet': False,
'cloak_email_addresses': True, 'cloak_email_addresses': True,
'pep_base_url': 'https://www.python.org/dev/peps/', 'pep_base_url': 'https://www.python.org/dev/peps/',
@ -55,7 +55,7 @@ default_settings = {
'halt_level': 5, 'halt_level': 5,
'file_insertion_enabled': True, 'file_insertion_enabled': True,
'smartquotes_locales': [], 'smartquotes_locales': [],
} # type: Dict[str, Any] }
# This is increased every time an environment attribute is added # This is increased every time an environment attribute is added
# or changed to properly invalidate pickle files. # or changed to properly invalidate pickle files.
@ -74,10 +74,10 @@ CONFIG_CHANGED_REASON = {
} }
versioning_conditions = { versioning_conditions: Dict[str, Union[bool, Callable]] = {
'none': False, 'none': False,
'text': is_translatable, 'text': is_translatable,
} # type: Dict[str, Union[bool, Callable]] }
class BuildEnvironment: class BuildEnvironment:
@ -87,24 +87,24 @@ class BuildEnvironment:
transformations to resolve links to them. transformations to resolve links to them.
""" """
domains = None # type: Dict[str, Domain] domains: Dict[str, Domain] = None
# --------- ENVIRONMENT INITIALIZATION ------------------------------------- # --------- ENVIRONMENT INITIALIZATION -------------------------------------
def __init__(self, app: "Sphinx" = None): def __init__(self, app: "Sphinx" = None):
self.app = None # type: Sphinx self.app: Sphinx = None
self.doctreedir = None # type: str self.doctreedir: str = None
self.srcdir = None # type: str self.srcdir: str = None
self.config = None # type: Config self.config: Config = None
self.config_status = None # type: int self.config_status: int = None
self.config_status_extra = None # type: str self.config_status_extra: str = None
self.events = None # type: EventManager self.events: EventManager = None
self.project = None # type: Project self.project: Project = None
self.version = None # type: Dict[str, str] self.version: Dict[str, str] = None
# the method of doctree versioning; see set_versioning_method # the method of doctree versioning; see set_versioning_method
self.versioning_condition = None # type: Union[bool, Callable] self.versioning_condition: Union[bool, Callable] = None
self.versioning_compare = None # type: bool self.versioning_compare: bool = None
# all the registered domains, set by the application # all the registered domains, set by the application
self.domains = {} self.domains = {}
@ -116,70 +116,67 @@ class BuildEnvironment:
# All "docnames" here are /-separated and relative and exclude # All "docnames" here are /-separated and relative and exclude
# the source suffix. # the source suffix.
self.all_docs = {} # type: Dict[str, float]
# docname -> mtime at the time of reading # docname -> mtime at the time of reading
# contains all read docnames # contains all read docnames
self.dependencies = defaultdict(set) # type: Dict[str, Set[str]] self.all_docs: Dict[str, float] = {}
# docname -> set of dependent file # docname -> set of dependent file
# names, relative to documentation root # names, relative to documentation root
self.included = defaultdict(set) # type: Dict[str, Set[str]] self.dependencies: Dict[str, Set[str]] = defaultdict(set)
# docname -> set of included file # docname -> set of included file
# docnames included from other documents # docnames included from other documents
self.reread_always = set() # type: Set[str] self.included: Dict[str, Set[str]] = defaultdict(set)
# docnames to re-read unconditionally on # docnames to re-read unconditionally on next build
# next build self.reread_always: Set[str] = set()
# File metadata # File metadata
self.metadata = defaultdict(dict) # type: Dict[str, Dict[str, Any]]
# docname -> dict of metadata items # docname -> dict of metadata items
self.metadata: Dict[str, Dict[str, Any]] = defaultdict(dict)
# TOC inventory # TOC inventory
self.titles = {} # type: Dict[str, nodes.title]
# docname -> title node # docname -> title node
self.longtitles = {} # type: Dict[str, nodes.title] self.titles: Dict[str, nodes.title] = {}
# docname -> title node; only different if # docname -> title node; only different if
# set differently with title directive # set differently with title directive
self.tocs = {} # type: Dict[str, nodes.bullet_list] self.longtitles: Dict[str, nodes.title] = {}
# docname -> table of contents nodetree # docname -> table of contents nodetree
self.toc_num_entries = {} # type: Dict[str, int] self.tocs: Dict[str, nodes.bullet_list] = {}
# docname -> number of real entries # docname -> number of real entries
self.toc_num_entries: Dict[str, int] = {}
# used to determine when to show the TOC # used to determine when to show the TOC
# in a sidebar (don't show if it's only one item) # in a sidebar (don't show if it's only one item)
self.toc_secnumbers = {} # type: Dict[str, Dict[str, Tuple[int, ...]]]
# docname -> dict of sectionid -> number # docname -> dict of sectionid -> number
self.toc_fignumbers = {} # type: Dict[str, Dict[str, Dict[str, Tuple[int, ...]]]] self.toc_secnumbers: Dict[str, Dict[str, Tuple[int, ...]]] = {}
# docname -> dict of figtype -> # docname -> dict of figtype -> dict of figureid -> number
# dict of figureid -> number self.toc_fignumbers: Dict[str, Dict[str, Dict[str, Tuple[int, ...]]]] = {}
self.toctree_includes = {} # type: Dict[str, List[str]]
# docname -> list of toctree includefiles # docname -> list of toctree includefiles
self.files_to_rebuild = {} # type: Dict[str, Set[str]] self.toctree_includes: Dict[str, List[str]] = {}
# docname -> set of files # docname -> set of files (containing its TOCs) to rebuild too
# (containing its TOCs) to rebuild too self.files_to_rebuild: Dict[str, Set[str]] = {}
self.glob_toctrees = set() # type: Set[str]
# docnames that have :glob: toctrees # docnames that have :glob: toctrees
self.numbered_toctrees = set() # type: Set[str] self.glob_toctrees: Set[str] = set()
# docnames that have :numbered: toctrees # docnames that have :numbered: toctrees
self.numbered_toctrees: Set[str] = set()
# domain-specific inventories, here to be pickled # domain-specific inventories, here to be pickled
self.domaindata = {} # type: Dict[str, Dict]
# domainname -> domain-specific dict # domainname -> domain-specific dict
self.domaindata: Dict[str, Dict] = {}
# these map absolute path -> (docnames, unique filename) # these map absolute path -> (docnames, unique filename)
self.images = FilenameUniqDict() # type: FilenameUniqDict self.images: FilenameUniqDict = FilenameUniqDict()
self.dlfiles = DownloadFiles() # type: DownloadFiles
# filename -> (set of docnames, destination) # filename -> (set of docnames, destination)
self.dlfiles: DownloadFiles = DownloadFiles()
# the original URI for images # the original URI for images
self.original_image_uri = {} # type: Dict[str, str] self.original_image_uri: Dict[str, str] = {}
# temporary data storage while reading a document # temporary data storage while reading a document
self.temp_data = {} # type: Dict[str, Any] self.temp_data: Dict[str, Any] = {}
# context for cross-references (e.g. current module or class) # context for cross-references (e.g. current module or class)
# this is similar to temp_data, but will for example be copied to # this is similar to temp_data, but will for example be copied to
# attributes of "any" cross references # attributes of "any" cross references
self.ref_context = {} # type: Dict[str, Any] self.ref_context: Dict[str, Any] = {}
# set up environment # set up environment
if app: if app:
@ -269,7 +266,7 @@ class BuildEnvironment:
raise an exception if the user tries to use an environment with an raise an exception if the user tries to use an environment with an
incompatible versioning method. incompatible versioning method.
""" """
condition = None # type: Union[bool, Callable] condition: Union[bool, Callable] = None
if callable(method): if callable(method):
condition = method condition = method
else: else:
@ -385,8 +382,8 @@ class BuildEnvironment:
# clear all files no longer present # clear all files no longer present
removed = set(self.all_docs) - self.found_docs removed = set(self.all_docs) - self.found_docs
added = set() # type: Set[str] added: Set[str] = set()
changed = set() # type: Set[str] changed: Set[str] = set()
if config_changed: if config_changed:
# config values affect e.g. substitutions # config values affect e.g. substitutions
@ -438,7 +435,7 @@ class BuildEnvironment:
return added, changed, removed return added, changed, removed
def check_dependents(self, app: "Sphinx", already: Set[str]) -> Generator[str, None, None]: def check_dependents(self, app: "Sphinx", already: Set[str]) -> Generator[str, None, None]:
to_rewrite = [] # type: List[str] to_rewrite: List[str] = []
for docnames in self.events.emit('env-get-updated', self): for docnames in self.events.emit('env-get-updated', self):
to_rewrite.extend(docnames) to_rewrite.extend(docnames)
for docname in set(to_rewrite): for docname in set(to_rewrite):

View File

@ -31,7 +31,7 @@ class IndexEntries:
_fixre: Pattern = re.compile(r'(.*) ([(][^()]*[)])') _fixre: Pattern = re.compile(r'(.*) ([(][^()]*[)])')
) -> List[Tuple[str, List[Tuple[str, Any]]]]: ) -> List[Tuple[str, List[Tuple[str, Any]]]]:
"""Create the real index from the collected index entries.""" """Create the real index from the collected index entries."""
new = {} # type: Dict[str, List] new: Dict[str, List] = {}
def add_entry(word: str, subword: str, main: str, link: bool = True, def add_entry(word: str, subword: str, main: str, link: bool = True,
dic: Dict = new, key: str = None) -> None: dic: Dict = new, key: str = None) -> None:
@ -126,7 +126,7 @@ class IndexEntries:
# (in module foo) # (in module foo)
# (in module bar) # (in module bar)
oldkey = '' oldkey = ''
oldsubitems = None # type: Dict[str, List] oldsubitems: Dict[str, List] = None
i = 0 i = 0
while i < len(newlist): while i < len(newlist):
key, (targets, subitems, _key) = newlist[i] key, (targets, subitems, _key) = newlist[i]

View File

@ -102,7 +102,7 @@ class TocTree:
if not subnode['anchorname']: if not subnode['anchorname']:
# give the whole branch a 'current' class # give the whole branch a 'current' class
# (useful for styling it differently) # (useful for styling it differently)
branchnode = subnode # type: Element branchnode: Element = subnode
while branchnode: while branchnode:
branchnode['classes'].append('current') branchnode['classes'].append('current')
branchnode = branchnode.parent branchnode = branchnode.parent
@ -119,7 +119,7 @@ class TocTree:
) -> List[Element]: ) -> List[Element]:
"""Return TOC entries for a toctree node.""" """Return TOC entries for a toctree node."""
refs = [(e[0], e[1]) for e in toctreenode['entries']] refs = [(e[0], e[1]) for e in toctreenode['entries']]
entries = [] # type: List[Element] entries: List[Element] = []
for (title, ref) in refs: for (title, ref) in refs:
try: try:
refdoc = None refdoc = None
@ -268,7 +268,7 @@ class TocTree:
for p, children in self.env.toctree_includes.items(): for p, children in self.env.toctree_includes.items():
for child in children: for child in children:
parent[child] = p parent[child] = p
ancestors = [] # type: List[str] ancestors: List[str] = []
d = docname d = docname
while d in parent and d not in ancestors: while d in parent and d not in ancestors:
ancestors.append(d) ancestors.append(d)
@ -316,7 +316,7 @@ class TocTree:
**kwargs: Any) -> Element: **kwargs: Any) -> Element:
"""Return the global TOC nodetree.""" """Return the global TOC nodetree."""
doctree = self.env.get_doctree(self.env.config.root_doc) doctree = self.env.get_doctree(self.env.config.root_doc)
toctrees = [] # type: List[Element] toctrees: List[Element] = []
if 'includehidden' not in kwargs: if 'includehidden' not in kwargs:
kwargs['includehidden'] = True kwargs['includehidden'] = True
if 'maxdepth' not in kwargs or not kwargs['maxdepth']: if 'maxdepth' not in kwargs or not kwargs['maxdepth']:

View File

@ -27,7 +27,7 @@ class EnvironmentCollector:
entries and toctrees, etc. entries and toctrees, etc.
""" """
listener_ids = None # type: Dict[str, int] listener_ids: Dict[str, int] = None
def enable(self, app: "Sphinx") -> None: def enable(self, app: "Sphinx") -> None:
assert self.listener_ids is None assert self.listener_ids is None

View File

@ -48,7 +48,7 @@ class ImageCollector(EnvironmentCollector):
# choose the best image from these candidates. The special key * is # choose the best image from these candidates. The special key * is
# set if there is only single candidate to be used by a writer. # set if there is only single candidate to be used by a writer.
# The special key ? is set for nonlocal URIs. # The special key ? is set for nonlocal URIs.
candidates = {} # type: Dict[str, str] candidates: Dict[str, str] = {}
node['candidates'] = candidates node['candidates'] = candidates
imguri = node['uri'] imguri = node['uri']
if imguri.startswith('data:'): if imguri.startswith('data:'):
@ -94,7 +94,7 @@ class ImageCollector(EnvironmentCollector):
def collect_candidates(self, env: BuildEnvironment, imgpath: str, def collect_candidates(self, env: BuildEnvironment, imgpath: str,
candidates: Dict[str, str], node: Node) -> None: candidates: Dict[str, str], node: Node) -> None:
globbed = {} # type: Dict[str, List[str]] globbed: Dict[str, List[str]] = {}
for filename in glob(imgpath): for filename in glob(imgpath):
new_imgpath = relative_path(path.join(env.srcdir, 'dummy'), new_imgpath = relative_path(path.join(env.srcdir, 'dummy'),
filename) filename)

View File

@ -64,7 +64,7 @@ class TocTreeCollector(EnvironmentCollector):
def traverse_in_section(node: Element, cls: "Type[N]") -> List[N]: def traverse_in_section(node: Element, cls: "Type[N]") -> List[N]:
"""Like traverse(), but stay within the same section.""" """Like traverse(), but stay within the same section."""
result = [] # type: List[N] result: List[N] = []
if isinstance(node, cls): if isinstance(node, cls):
result.append(node) result.append(node)
for child in node.children: for child in node.children:
@ -75,7 +75,7 @@ class TocTreeCollector(EnvironmentCollector):
return result return result
def build_toc(node: Element, depth: int = 1) -> nodes.bullet_list: def build_toc(node: Element, depth: int = 1) -> nodes.bullet_list:
entries = [] # type: List[Element] entries: List[Element] = []
for sectionnode in node: for sectionnode in node:
# find all toctree nodes in this section and add them # find all toctree nodes in this section and add them
# to the toc (just copying the toctree node which is then # to the toc (just copying the toctree node which is then
@ -100,7 +100,7 @@ class TocTreeCollector(EnvironmentCollector):
'', '', internal=True, refuri=docname, '', '', internal=True, refuri=docname,
anchorname=anchorname, *nodetext) anchorname=anchorname, *nodetext)
para = addnodes.compact_paragraph('', '', reference) para = addnodes.compact_paragraph('', '', reference)
item = nodes.list_item('', para) # type: Element item: Element = nodes.list_item('', para)
sub_item = build_toc(sectionnode, depth + 1) sub_item = build_toc(sectionnode, depth + 1)
if sub_item: if sub_item:
item += sub_item item += sub_item
@ -136,7 +136,7 @@ class TocTreeCollector(EnvironmentCollector):
# a list of all docnames whose section numbers changed # a list of all docnames whose section numbers changed
rewrite_needed = [] rewrite_needed = []
assigned = set() # type: Set[str] assigned: Set[str] = set()
old_secnumbers = env.toc_secnumbers old_secnumbers = env.toc_secnumbers
env.toc_secnumbers = {} env.toc_secnumbers = {}
@ -186,7 +186,7 @@ class TocTreeCollector(EnvironmentCollector):
'(nested numbered toctree?)'), ref, '(nested numbered toctree?)'), ref,
location=toctreenode, type='toc', subtype='secnum') location=toctreenode, type='toc', subtype='secnum')
elif ref in env.tocs: elif ref in env.tocs:
secnums = {} # type: Dict[str, Tuple[int, ...]] secnums: Dict[str, Tuple[int, ...]] = {}
env.toc_secnumbers[ref] = secnums env.toc_secnumbers[ref] = secnums
assigned.add(ref) assigned.add(ref)
_walk_toc(env.tocs[ref], secnums, depth, env.titles.get(ref)) _walk_toc(env.tocs[ref], secnums, depth, env.titles.get(ref))
@ -210,10 +210,10 @@ class TocTreeCollector(EnvironmentCollector):
rewrite_needed = [] rewrite_needed = []
assigned = set() # type: Set[str] assigned: Set[str] = set()
old_fignumbers = env.toc_fignumbers old_fignumbers = env.toc_fignumbers
env.toc_fignumbers = {} env.toc_fignumbers = {}
fignum_counter = {} # type: Dict[str, Dict[Tuple[int, ...], int]] fignum_counter: Dict[str, Dict[Tuple[int, ...], int]] = {}
def get_figtype(node: Node) -> str: def get_figtype(node: Node) -> str:
for domain in env.domains.values(): for domain in env.domains.values():