Merge pull request #6954 from tk0miya/refactor_type_annotation2

Migrate to py3 style type annotation: addnodes, cmdline, deprecation, errors, events and extensio
This commit is contained in:
Takeshi KOMIYA
2019-12-25 02:23:59 +09:00
committed by GitHub
6 changed files with 55 additions and 97 deletions

View File

@@ -9,6 +9,7 @@
"""
import warnings
from typing import Any, Dict, List, Sequence
from docutils import nodes
@@ -16,8 +17,7 @@ from sphinx.deprecation import RemovedInSphinx30Warning, RemovedInSphinx40Warnin
if False:
# For type annotation
from typing import Any, Dict, List, Sequence # NOQA
from sphinx.application import Sphinx # NOQA
from sphinx.application import Sphinx
class translatable(nodes.Node):
@@ -34,18 +34,15 @@ class translatable(nodes.Node):
Because they are used at final step; extraction.
"""
def preserve_original_messages(self):
# type: () -> None
def preserve_original_messages(self) -> None:
"""Preserve original translatable messages."""
raise NotImplementedError
def apply_translated_message(self, original_message, translated_message):
# type: (str, str) -> None
def apply_translated_message(self, original_message: str, translated_message: str) -> None:
"""Apply translated message."""
raise NotImplementedError
def extract_original_messages(self):
# type: () -> Sequence[str]
def extract_original_messages(self) -> Sequence[str]:
"""Extract translation messages.
:returns: list of extracted messages or messages generator
@@ -61,8 +58,7 @@ class not_smartquotable:
class toctree(nodes.General, nodes.Element, translatable):
"""Node for inserting a "TOC tree"."""
def preserve_original_messages(self):
# type: () -> None
def preserve_original_messages(self) -> None:
# toctree entries
rawentries = self.setdefault('rawentries', [])
for title, docname in self['entries']:
@@ -73,8 +69,7 @@ class toctree(nodes.General, nodes.Element, translatable):
if self.get('caption'):
self['rawcaption'] = self['caption']
def apply_translated_message(self, original_message, translated_message):
# type: (str, str) -> None
def apply_translated_message(self, original_message: str, translated_message: str) -> None:
# toctree entries
for i, (title, docname) in enumerate(self['entries']):
if title == original_message:
@@ -84,8 +79,7 @@ class toctree(nodes.General, nodes.Element, translatable):
if self.get('rawcaption') == original_message:
self['caption'] = translated_message
def extract_original_messages(self):
# type: () -> List[str]
def extract_original_messages(self) -> List[str]:
messages = [] # type: List[str]
# toctree entries
@@ -143,8 +137,7 @@ class desc_type(nodes.Part, nodes.Inline, nodes.FixedTextElement):
class desc_returns(desc_type):
"""Node for a "returns" annotation (a la -> in Python)."""
def astext(self):
# type: () -> str
def astext(self) -> str:
return ' -> ' + super().astext()
@@ -165,8 +158,7 @@ class desc_optional(nodes.Part, nodes.Inline, nodes.FixedTextElement):
"""Node for marking optional parts of the parameter list."""
child_text_separator = ', '
def astext(self):
# type: () -> str
def astext(self) -> str:
return '[' + super().astext() + ']'
@@ -366,8 +358,7 @@ class abbreviation(nodes.abbreviation):
.. deprecated:: 2.0
"""
def __init__(self, rawsource='', text='', *children, **attributes):
# type: (str, str, *nodes.Node, **Any) -> None
def __init__(self, rawsource: str = '', text: str = '', *children, **attributes) -> None:
warnings.warn("abbrevition node for Sphinx was replaced by docutils'.",
RemovedInSphinx40Warning, stacklevel=2)
@@ -378,8 +369,7 @@ class manpage(nodes.Inline, nodes.FixedTextElement):
"""Node for references to manpages."""
def setup(app):
# type: (Sphinx) -> Dict[str, Any]
def setup(app: "Sphinx") -> Dict[str, Any]:
app.add_node(toctree)
app.add_node(desc)
app.add_node(desc_signature)

View File

@@ -8,42 +8,36 @@
:license: BSD, see LICENSE for details.
"""
import argparse
import sys
import warnings
from typing import Any, IO, List, Union
from sphinx.application import Sphinx
from sphinx.cmd import build
from sphinx.deprecation import RemovedInSphinx30Warning
if False:
# For type annotation
import argparse # NOQA
from typing import Any, IO, List, Union # NOQA
from sphinx.application import Sphinx # NOQA
def handle_exception(app, args, exception, stderr=sys.stderr):
# type: (Sphinx, Any, Union[Exception, KeyboardInterrupt], IO) -> None
def handle_exception(app: Sphinx, args: Any, exception: Union[Exception, KeyboardInterrupt],
stderr: IO = sys.stderr) -> None:
warnings.warn('sphinx.cmdline module is deprecated. Use sphinx.cmd.build instead.',
RemovedInSphinx30Warning, stacklevel=2)
build.handle_exception(app, args, exception, stderr)
def jobs_argument(value):
# type: (str) -> int
def jobs_argument(value: str) -> int:
warnings.warn('sphinx.cmdline module is deprecated. Use sphinx.cmd.build instead.',
RemovedInSphinx30Warning, stacklevel=2)
return build.jobs_argument(value)
def get_parser():
# type: () -> argparse.ArgumentParser
def get_parser() -> argparse.ArgumentParser:
warnings.warn('sphinx.cmdline module is deprecated. Use sphinx.cmd.build instead.',
RemovedInSphinx30Warning, stacklevel=2)
return build.get_parser()
def main(argv=sys.argv[1:]):
# type: (List[str]) -> int
def main(argv: List[str] = sys.argv[1:]) -> int:
warnings.warn('sphinx.cmdline module is deprecated. Use sphinx.cmd.build instead.',
RemovedInSphinx30Warning, stacklevel=2)
return build.main(argv)

View File

@@ -11,11 +11,8 @@
import sys
import warnings
from importlib import import_module
if False:
# For type annotation
from typing import Any, Dict # NOQA
from typing import Type # for python3.5.1
from typing import Any, Dict
from typing import Type # for python3.5.1
class RemovedInSphinx30Warning(DeprecationWarning):
@@ -29,22 +26,20 @@ class RemovedInSphinx40Warning(PendingDeprecationWarning):
RemovedInNextVersionWarning = RemovedInSphinx30Warning
def deprecated_alias(modname, objects, warning):
# type: (str, Dict, Type[Warning]) -> None
def deprecated_alias(modname: str, objects: Dict, warning: Type[Warning]) -> None:
module = import_module(modname)
sys.modules[modname] = _ModuleWrapper(module, modname, objects, warning) # type: ignore
class _ModuleWrapper:
def __init__(self, module, modname, objects, warning):
# type: (Any, str, Dict, Type[Warning]) -> None
def __init__(self, module: Any, modname: str, objects: Dict, warning: Type[Warning]
) -> None:
self._module = module
self._modname = modname
self._objects = objects
self._warning = warning
def __getattr__(self, name):
# type: (str) -> Any
def __getattr__(self, name: str) -> Any:
if name in self._objects:
warnings.warn("%s.%s is deprecated. Check CHANGES for Sphinx "
"API modifications." % (self._modname, name),
@@ -57,33 +52,27 @@ class _ModuleWrapper:
class DeprecatedDict(dict):
"""A deprecated dict which warns on each access."""
def __init__(self, data, message, warning):
# type: (Dict, str, Type[Warning]) -> None
def __init__(self, data: Dict, message: str, warning: Type[Warning]) -> None:
self.message = message
self.warning = warning
super().__init__(data)
def __setitem__(self, key, value):
# type: (str, Any) -> None
def __setitem__(self, key: str, value: Any) -> None:
warnings.warn(self.message, self.warning, stacklevel=2)
super().__setitem__(key, value)
def setdefault(self, key, default=None):
# type: (str, Any) -> None
def setdefault(self, key: str, default: Any = None) -> Any:
warnings.warn(self.message, self.warning, stacklevel=2)
return super().setdefault(key, default)
def __getitem__(self, key):
# type: (str) -> None
def __getitem__(self, key: str) -> None:
warnings.warn(self.message, self.warning, stacklevel=2)
return super().__getitem__(key)
def get(self, key, default=None):
# type: (str, Any) -> None
def get(self, key: str, default: Any = None) -> Any:
warnings.warn(self.message, self.warning, stacklevel=2)
return super().get(key, default)
def update(self, other=None): # type: ignore
# type: (Dict) -> None
def update(self, other: Dict = None) -> None: # type: ignore
warnings.warn(self.message, self.warning, stacklevel=2)
super().update(other)

View File

@@ -9,9 +9,7 @@
:license: BSD, see LICENSE for details.
"""
if False:
# For type annotation
from typing import Any # NOQA
from typing import Any
class SphinxError(Exception):
@@ -51,21 +49,18 @@ class ExtensionError(SphinxError):
"""Extension error."""
category = 'Extension error'
def __init__(self, message, orig_exc=None):
# type: (str, Exception) -> None
def __init__(self, message: str, orig_exc: Exception = None) -> None:
super().__init__(message)
self.message = message
self.orig_exc = orig_exc
def __repr__(self):
# type: () -> str
def __repr__(self) -> str:
if self.orig_exc:
return '%s(%r, %r)' % (self.__class__.__name__,
self.message, self.orig_exc)
return '%s(%r)' % (self.__class__.__name__, self.message)
def __str__(self):
# type: () -> str
def __str__(self) -> str:
parent_str = super().__str__()
if self.orig_exc:
return '%s (exception: %s)' % (parent_str, self.orig_exc)
@@ -102,21 +97,18 @@ class SphinxParallelError(SphinxError):
category = 'Sphinx parallel build error'
def __init__(self, message, traceback):
# type: (str, Any) -> None
def __init__(self, message: str, traceback: Any) -> None:
self.message = message
self.traceback = traceback
def __str__(self):
# type: () -> str
def __str__(self) -> str:
return self.message
class PycodeError(Exception):
"""Pycode Python source code analyser error."""
def __str__(self):
# type: () -> str
def __str__(self) -> str:
res = self.args[0]
if len(self.args) > 1:
res += ' (exception was: %r)' % self.args[1]

View File

@@ -12,6 +12,7 @@
import warnings
from collections import OrderedDict, defaultdict
from typing import Any, Callable, Dict, List
from sphinx.deprecation import RemovedInSphinx40Warning
from sphinx.errors import ExtensionError
@@ -20,8 +21,8 @@ from sphinx.util import logging
if False:
# For type annotation
from typing import Any, Callable, Dict, List # NOQA
from sphinx.application import Sphinx # NOQA
from sphinx.application import Sphinx
logger = logging.getLogger(__name__)
@@ -50,8 +51,7 @@ core_events = {
class EventManager:
"""Event manager for Sphinx."""
def __init__(self, app=None):
# type: (Sphinx) -> None
def __init__(self, app: "Sphinx" = None) -> None:
if app is None:
warnings.warn('app argument is required for EventManager.',
RemovedInSphinx40Warning)
@@ -60,15 +60,13 @@ class EventManager:
self.listeners = defaultdict(OrderedDict) # type: Dict[str, Dict[int, Callable]]
self.next_listener_id = 0
def add(self, name):
# type: (str) -> None
def add(self, name: str) -> None:
"""Register a custom Sphinx event."""
if name in self.events:
raise ExtensionError(__('Event %r already present') % name)
self.events[name] = ''
def connect(self, name, callback):
# type: (str, Callable) -> int
def connect(self, name: str, callback: Callable) -> int:
"""Connect a handler to specific event."""
if name not in self.events:
raise ExtensionError(__('Unknown event name: %s') % name)
@@ -78,14 +76,12 @@ class EventManager:
self.listeners[name][listener_id] = callback
return listener_id
def disconnect(self, listener_id):
# type: (int) -> None
def disconnect(self, listener_id: int) -> None:
"""Disconnect a handler."""
for event in self.listeners.values():
event.pop(listener_id, None)
def emit(self, name, *args):
# type: (str, Any) -> List
def emit(self, name: str, *args) -> List:
"""Emit a Sphinx event."""
try:
logger.debug('[app] emitting event: %r%s', name, repr(args)[:100])
@@ -103,8 +99,7 @@ class EventManager:
results.append(callback(self.app, *args))
return results
def emit_firstresult(self, name, *args):
# type: (str, Any) -> Any
def emit_firstresult(self, name: str, *args) -> Any:
"""Emit a Sphinx event and returns first result.
This returns the result of the first handler that doesn't return ``None``.

View File

@@ -8,22 +8,22 @@
:license: BSD, see LICENSE for details.
"""
from typing import Any, Dict
from sphinx.config import Config
from sphinx.errors import VersionRequirementError
from sphinx.locale import __
from sphinx.util import logging
if False:
# For type annotation
from typing import Any, Dict # NOQA
from sphinx.application import Sphinx # NOQA
from sphinx.config import Config # NOQA
from sphinx.application import Sphinx
logger = logging.getLogger(__name__)
class Extension:
def __init__(self, name, module, **kwargs):
# type: (str, Any, Any) -> None
def __init__(self, name: str, module: Any, **kwargs) -> None:
self.name = name
self.module = module
self.metadata = kwargs
@@ -40,8 +40,7 @@ class Extension:
self.parallel_write_safe = kwargs.pop('parallel_write_safe', True)
def verify_needs_extensions(app, config):
# type: (Sphinx, Config) -> None
def verify_needs_extensions(app: "Sphinx", config: Config) -> None:
"""Verify the required Sphinx extensions are loaded."""
if config.needs_extensions is None:
return
@@ -60,8 +59,7 @@ def verify_needs_extensions(app, config):
(extname, reqversion, extension.version))
def setup(app):
# type: (Sphinx) -> Dict[str, Any]
def setup(app: "Sphinx") -> Dict[str, Any]:
app.connect('config-inited', verify_needs_extensions)
return {