mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge pull request #6952 from tk0miya/refactor_type_annotation_io
Migrate to py3 style type annotation: sphinx.io and sphinx.parsers
This commit is contained in:
86
sphinx/io.py
86
sphinx/io.py
@@ -9,19 +9,25 @@
|
|||||||
"""
|
"""
|
||||||
import codecs
|
import codecs
|
||||||
import warnings
|
import warnings
|
||||||
from typing import Any
|
from typing import Any, List, Tuple
|
||||||
|
from typing import Type # for python3.5.1
|
||||||
|
|
||||||
|
from docutils import nodes
|
||||||
from docutils.core import Publisher
|
from docutils.core import Publisher
|
||||||
from docutils.io import FileInput, NullOutput
|
from docutils.frontend import Values
|
||||||
|
from docutils.io import FileInput, Input, NullOutput
|
||||||
|
from docutils.parsers import Parser
|
||||||
from docutils.parsers.rst import Parser as RSTParser
|
from docutils.parsers.rst import Parser as RSTParser
|
||||||
from docutils.readers import standalone
|
from docutils.readers import standalone
|
||||||
from docutils.statemachine import StringList, string2lines
|
from docutils.statemachine import StringList, string2lines
|
||||||
|
from docutils.transforms import Transform
|
||||||
from docutils.transforms.references import DanglingReferences
|
from docutils.transforms.references import DanglingReferences
|
||||||
from docutils.writers import UnfilteredWriter
|
from docutils.writers import UnfilteredWriter
|
||||||
|
|
||||||
from sphinx.deprecation import (
|
from sphinx.deprecation import (
|
||||||
RemovedInSphinx30Warning, RemovedInSphinx40Warning, deprecated_alias
|
RemovedInSphinx30Warning, RemovedInSphinx40Warning, deprecated_alias
|
||||||
)
|
)
|
||||||
|
from sphinx.environment import BuildEnvironment
|
||||||
from sphinx.errors import FiletypeNotFoundError
|
from sphinx.errors import FiletypeNotFoundError
|
||||||
from sphinx.transforms import (
|
from sphinx.transforms import (
|
||||||
AutoIndexUpgrader, DoctreeReadEvent, FigureAligner, SphinxTransformer
|
AutoIndexUpgrader, DoctreeReadEvent, FigureAligner, SphinxTransformer
|
||||||
@@ -38,15 +44,7 @@ from sphinx.versioning import UIDTransform
|
|||||||
|
|
||||||
if False:
|
if False:
|
||||||
# For type annotation
|
# For type annotation
|
||||||
from typing import Dict, List, Tuple # NOQA
|
from sphinx.application import Sphinx
|
||||||
from typing import Type # for python3.5.1
|
|
||||||
from docutils import nodes # NOQA
|
|
||||||
from docutils.frontend import Values # NOQA
|
|
||||||
from docutils.io import Input # NOQA
|
|
||||||
from docutils.parsers import Parser # NOQA
|
|
||||||
from docutils.transforms import Transform # NOQA
|
|
||||||
from sphinx.application import Sphinx # NOQA
|
|
||||||
from sphinx.environment import BuildEnvironment # NOQA
|
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@@ -61,8 +59,7 @@ class SphinxBaseReader(standalone.Reader):
|
|||||||
|
|
||||||
transforms = [] # type: List[Type[Transform]]
|
transforms = [] # type: List[Type[Transform]]
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs) -> None:
|
||||||
# type: (Any, Any) -> None
|
|
||||||
from sphinx.application import Sphinx
|
from sphinx.application import Sphinx
|
||||||
if len(args) > 0 and isinstance(args[0], Sphinx):
|
if len(args) > 0 and isinstance(args[0], Sphinx):
|
||||||
self._app = args[0]
|
self._app = args[0]
|
||||||
@@ -72,26 +69,22 @@ class SphinxBaseReader(standalone.Reader):
|
|||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def app(self):
|
def app(self) -> "Sphinx":
|
||||||
# type: () -> Sphinx
|
|
||||||
warnings.warn('SphinxBaseReader.app is deprecated.',
|
warnings.warn('SphinxBaseReader.app is deprecated.',
|
||||||
RemovedInSphinx40Warning, stacklevel=2)
|
RemovedInSphinx40Warning, stacklevel=2)
|
||||||
return self._app
|
return self._app
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def env(self):
|
def env(self) -> BuildEnvironment:
|
||||||
# type: () -> BuildEnvironment
|
|
||||||
warnings.warn('SphinxBaseReader.env is deprecated.',
|
warnings.warn('SphinxBaseReader.env is deprecated.',
|
||||||
RemovedInSphinx40Warning, stacklevel=2)
|
RemovedInSphinx40Warning, stacklevel=2)
|
||||||
return self._env
|
return self._env
|
||||||
|
|
||||||
def setup(self, app):
|
def setup(self, app: "Sphinx") -> None:
|
||||||
# type: (Sphinx) -> None
|
|
||||||
self._app = app # hold application object only for compatibility
|
self._app = app # hold application object only for compatibility
|
||||||
self._env = app.env
|
self._env = app.env
|
||||||
|
|
||||||
def get_transforms(self):
|
def get_transforms(self) -> List[Type[Transform]]:
|
||||||
# type: () -> List[Type[Transform]]
|
|
||||||
transforms = super().get_transforms() + self.transforms
|
transforms = super().get_transforms() + self.transforms
|
||||||
|
|
||||||
# remove transforms which is not needed for Sphinx
|
# remove transforms which is not needed for Sphinx
|
||||||
@@ -102,8 +95,7 @@ class SphinxBaseReader(standalone.Reader):
|
|||||||
|
|
||||||
return transforms
|
return transforms
|
||||||
|
|
||||||
def new_document(self):
|
def new_document(self) -> nodes.document:
|
||||||
# type: () -> nodes.document
|
|
||||||
"""Creates a new document object which having a special reporter object good
|
"""Creates a new document object which having a special reporter object good
|
||||||
for logging.
|
for logging.
|
||||||
"""
|
"""
|
||||||
@@ -125,13 +117,11 @@ class SphinxStandaloneReader(SphinxBaseReader):
|
|||||||
A basic document reader for Sphinx.
|
A basic document reader for Sphinx.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def setup(self, app):
|
def setup(self, app: "Sphinx") -> None:
|
||||||
# type: (Sphinx) -> None
|
|
||||||
self.transforms = self.transforms + app.registry.get_transforms()
|
self.transforms = self.transforms + app.registry.get_transforms()
|
||||||
super().setup(app)
|
super().setup(app)
|
||||||
|
|
||||||
def read(self, source, parser, settings):
|
def read(self, source: Input, parser: Parser, settings: Values) -> nodes.document:
|
||||||
# type: (Input, Parser, Values) -> nodes.document
|
|
||||||
self.source = source
|
self.source = source
|
||||||
if not self.parser:
|
if not self.parser:
|
||||||
self.parser = parser
|
self.parser = parser
|
||||||
@@ -140,8 +130,7 @@ class SphinxStandaloneReader(SphinxBaseReader):
|
|||||||
self.parse()
|
self.parse()
|
||||||
return self.document
|
return self.document
|
||||||
|
|
||||||
def read_source(self, env):
|
def read_source(self, env: BuildEnvironment) -> str:
|
||||||
# type: (BuildEnvironment) -> str
|
|
||||||
"""Read content from source and do post-process."""
|
"""Read content from source and do post-process."""
|
||||||
content = self.source.read()
|
content = self.source.read()
|
||||||
|
|
||||||
@@ -160,8 +149,7 @@ class SphinxI18nReader(SphinxBaseReader):
|
|||||||
Because the translated texts are partial and they don't have correct line numbers.
|
Because the translated texts are partial and they don't have correct line numbers.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def setup(self, app):
|
def setup(self, app: "Sphinx") -> None:
|
||||||
# type: (Sphinx) -> None
|
|
||||||
super().setup(app)
|
super().setup(app)
|
||||||
|
|
||||||
self.transforms = self.transforms + app.registry.get_transforms()
|
self.transforms = self.transforms + app.registry.get_transforms()
|
||||||
@@ -172,15 +160,13 @@ class SphinxI18nReader(SphinxBaseReader):
|
|||||||
if transform in self.transforms:
|
if transform in self.transforms:
|
||||||
self.transforms.remove(transform)
|
self.transforms.remove(transform)
|
||||||
|
|
||||||
def set_lineno_for_reporter(self, lineno):
|
def set_lineno_for_reporter(self, lineno: int) -> None:
|
||||||
# type: (int) -> None
|
|
||||||
"""Stores the source line number of original text."""
|
"""Stores the source line number of original text."""
|
||||||
warnings.warn('SphinxI18nReader.set_lineno_for_reporter() is deprecated.',
|
warnings.warn('SphinxI18nReader.set_lineno_for_reporter() is deprecated.',
|
||||||
RemovedInSphinx30Warning, stacklevel=2)
|
RemovedInSphinx30Warning, stacklevel=2)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def line(self):
|
def line(self) -> int:
|
||||||
# type: () -> int
|
|
||||||
warnings.warn('SphinxI18nReader.line is deprecated.',
|
warnings.warn('SphinxI18nReader.line is deprecated.',
|
||||||
RemovedInSphinx30Warning, stacklevel=2)
|
RemovedInSphinx30Warning, stacklevel=2)
|
||||||
return 0
|
return 0
|
||||||
@@ -191,13 +177,11 @@ class SphinxDummyWriter(UnfilteredWriter):
|
|||||||
|
|
||||||
supported = ('html',) # needed to keep "meta" nodes
|
supported = ('html',) # needed to keep "meta" nodes
|
||||||
|
|
||||||
def translate(self):
|
def translate(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def SphinxDummySourceClass(source, *args, **kwargs):
|
def SphinxDummySourceClass(source: Any, *args, **kwargs) -> Any:
|
||||||
# type: (Any, Any, Any) -> Any
|
|
||||||
"""Bypass source object as is to cheat Publisher."""
|
"""Bypass source object as is to cheat Publisher."""
|
||||||
return source
|
return source
|
||||||
|
|
||||||
@@ -208,8 +192,7 @@ class SphinxBaseFileInput(FileInput):
|
|||||||
It supports to replace unknown Unicode characters to '?'.
|
It supports to replace unknown Unicode characters to '?'.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, app, env, *args, **kwds):
|
def __init__(self, app: "Sphinx", env: BuildEnvironment, *args, **kwds) -> None:
|
||||||
# type: (Sphinx, BuildEnvironment, Any, Any) -> None
|
|
||||||
self.app = app
|
self.app = app
|
||||||
self.env = env
|
self.env = env
|
||||||
|
|
||||||
@@ -219,8 +202,7 @@ class SphinxBaseFileInput(FileInput):
|
|||||||
kwds['error_handler'] = 'sphinx' # py3: handle error on open.
|
kwds['error_handler'] = 'sphinx' # py3: handle error on open.
|
||||||
super().__init__(*args, **kwds)
|
super().__init__(*args, **kwds)
|
||||||
|
|
||||||
def warn_and_replace(self, error):
|
def warn_and_replace(self, error: Any) -> Tuple:
|
||||||
# type: (Any) -> Tuple
|
|
||||||
return UnicodeDecodeErrorHandler(self.env.docname)(error)
|
return UnicodeDecodeErrorHandler(self.env.docname)(error)
|
||||||
|
|
||||||
|
|
||||||
@@ -228,8 +210,7 @@ class SphinxFileInput(FileInput):
|
|||||||
"""A basic FileInput for Sphinx."""
|
"""A basic FileInput for Sphinx."""
|
||||||
supported = ('*',) # RemovedInSphinx30Warning
|
supported = ('*',) # RemovedInSphinx30Warning
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs) -> None:
|
||||||
# type: (Any, Any) -> None
|
|
||||||
kwargs['error_handler'] = 'sphinx'
|
kwargs['error_handler'] = 'sphinx'
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
@@ -250,8 +231,7 @@ class SphinxRSTFileInput(SphinxBaseFileInput):
|
|||||||
"""
|
"""
|
||||||
supported = ('restructuredtext',)
|
supported = ('restructuredtext',)
|
||||||
|
|
||||||
def prepend_prolog(self, text, prolog):
|
def prepend_prolog(self, text: StringList, prolog: str) -> None:
|
||||||
# type: (StringList, str) -> None
|
|
||||||
docinfo = self.count_docinfo_lines(text)
|
docinfo = self.count_docinfo_lines(text)
|
||||||
if docinfo:
|
if docinfo:
|
||||||
# insert a blank line after docinfo
|
# insert a blank line after docinfo
|
||||||
@@ -264,15 +244,13 @@ class SphinxRSTFileInput(SphinxBaseFileInput):
|
|||||||
|
|
||||||
text.insert(docinfo + lineno + 1, '', '<generated>', 0)
|
text.insert(docinfo + lineno + 1, '', '<generated>', 0)
|
||||||
|
|
||||||
def append_epilog(self, text, epilog):
|
def append_epilog(self, text: StringList, epilog: str) -> None:
|
||||||
# type: (StringList, str) -> None
|
|
||||||
# append a blank line and rst_epilog
|
# append a blank line and rst_epilog
|
||||||
text.append('', '<generated>', 0)
|
text.append('', '<generated>', 0)
|
||||||
for lineno, line in enumerate(epilog.splitlines()):
|
for lineno, line in enumerate(epilog.splitlines()):
|
||||||
text.append(line, '<rst_epilog>', lineno)
|
text.append(line, '<rst_epilog>', lineno)
|
||||||
|
|
||||||
def read(self): # type: ignore
|
def read(self) -> StringList: # type: ignore
|
||||||
# type: () -> StringList
|
|
||||||
inputstring = super().read()
|
inputstring = super().read()
|
||||||
lines = string2lines(inputstring, convert_whitespace=True)
|
lines = string2lines(inputstring, convert_whitespace=True)
|
||||||
content = StringList()
|
content = StringList()
|
||||||
@@ -284,8 +262,7 @@ class SphinxRSTFileInput(SphinxBaseFileInput):
|
|||||||
|
|
||||||
return content
|
return content
|
||||||
|
|
||||||
def count_docinfo_lines(self, content):
|
def count_docinfo_lines(self, content: StringList) -> int:
|
||||||
# type: (StringList) -> int
|
|
||||||
if len(content) == 0:
|
if len(content) == 0:
|
||||||
return 0
|
return 0
|
||||||
else:
|
else:
|
||||||
@@ -295,8 +272,7 @@ class SphinxRSTFileInput(SphinxBaseFileInput):
|
|||||||
return lineno
|
return lineno
|
||||||
|
|
||||||
|
|
||||||
def read_doc(app, env, filename):
|
def read_doc(app: "Sphinx", env: BuildEnvironment, filename: str) -> nodes.document:
|
||||||
# type: (Sphinx, BuildEnvironment, str) -> nodes.document
|
|
||||||
"""Parse a document and convert to doctree."""
|
"""Parse a document and convert to doctree."""
|
||||||
# set up error_handler for the target document
|
# set up error_handler for the target document
|
||||||
error_handler = UnicodeDecodeErrorHandler(env.docname)
|
error_handler = UnicodeDecodeErrorHandler(env.docname)
|
||||||
|
|||||||
@@ -8,8 +8,11 @@
|
|||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from typing import Any, Dict, List, Union
|
||||||
|
|
||||||
import docutils.parsers
|
import docutils.parsers
|
||||||
import docutils.parsers.rst
|
import docutils.parsers.rst
|
||||||
|
from docutils import nodes
|
||||||
from docutils.parsers.rst import states
|
from docutils.parsers.rst import states
|
||||||
from docutils.statemachine import StringList
|
from docutils.statemachine import StringList
|
||||||
from docutils.transforms.universal import SmartQuotes
|
from docutils.transforms.universal import SmartQuotes
|
||||||
@@ -18,11 +21,9 @@ from sphinx.util.rst import append_epilog, prepend_prolog
|
|||||||
|
|
||||||
if False:
|
if False:
|
||||||
# For type annotation
|
# For type annotation
|
||||||
from typing import Any, Dict, List, Union # NOQA
|
|
||||||
from typing import Type # for python3.5.1
|
|
||||||
from docutils import nodes # NOQA
|
|
||||||
from docutils.transforms import Transform # NOQA
|
from docutils.transforms import Transform # NOQA
|
||||||
from sphinx.application import Sphinx # NOQA
|
from typing import Type # NOQA # for python3.5.1
|
||||||
|
from sphinx.application import Sphinx
|
||||||
|
|
||||||
|
|
||||||
class Parser(docutils.parsers.Parser):
|
class Parser(docutils.parsers.Parser):
|
||||||
@@ -48,8 +49,7 @@ class Parser(docutils.parsers.Parser):
|
|||||||
``warn()`` and ``info()`` is deprecated. Use :mod:`sphinx.util.logging` instead.
|
``warn()`` and ``info()`` is deprecated. Use :mod:`sphinx.util.logging` instead.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def set_application(self, app):
|
def set_application(self, app: "Sphinx") -> None:
|
||||||
# type: (Sphinx) -> None
|
|
||||||
"""set_application will be called from Sphinx to set app and other instance variables
|
"""set_application will be called from Sphinx to set app and other instance variables
|
||||||
|
|
||||||
:param sphinx.application.Sphinx app: Sphinx application object
|
:param sphinx.application.Sphinx app: Sphinx application object
|
||||||
@@ -62,8 +62,7 @@ class Parser(docutils.parsers.Parser):
|
|||||||
class RSTParser(docutils.parsers.rst.Parser, Parser):
|
class RSTParser(docutils.parsers.rst.Parser, Parser):
|
||||||
"""A reST parser for Sphinx."""
|
"""A reST parser for Sphinx."""
|
||||||
|
|
||||||
def get_transforms(self):
|
def get_transforms(self) -> List["Type[Transform]"]:
|
||||||
# type: () -> List[Type[Transform]]
|
|
||||||
"""Sphinx's reST parser replaces a transform class for smart-quotes by own's
|
"""Sphinx's reST parser replaces a transform class for smart-quotes by own's
|
||||||
|
|
||||||
refs: sphinx.io.SphinxStandaloneReader
|
refs: sphinx.io.SphinxStandaloneReader
|
||||||
@@ -72,8 +71,7 @@ class RSTParser(docutils.parsers.rst.Parser, Parser):
|
|||||||
transforms.remove(SmartQuotes)
|
transforms.remove(SmartQuotes)
|
||||||
return transforms
|
return transforms
|
||||||
|
|
||||||
def parse(self, inputstring, document):
|
def parse(self, inputstring: Union[str, StringList], document: nodes.document) -> None:
|
||||||
# type: (Union[str, StringList], nodes.document) -> None
|
|
||||||
"""Parse text and generate a document tree."""
|
"""Parse text and generate a document tree."""
|
||||||
self.setup_parse(inputstring, document) # type: ignore
|
self.setup_parse(inputstring, document) # type: ignore
|
||||||
self.statemachine = states.RSTStateMachine(
|
self.statemachine = states.RSTStateMachine(
|
||||||
@@ -95,15 +93,13 @@ class RSTParser(docutils.parsers.rst.Parser, Parser):
|
|||||||
self.statemachine.run(inputlines, document, inliner=self.inliner)
|
self.statemachine.run(inputlines, document, inliner=self.inliner)
|
||||||
self.finish_parse()
|
self.finish_parse()
|
||||||
|
|
||||||
def decorate(self, content):
|
def decorate(self, content: StringList) -> None:
|
||||||
# type: (StringList) -> None
|
|
||||||
"""Preprocess reST content before parsing."""
|
"""Preprocess reST content before parsing."""
|
||||||
prepend_prolog(content, self.config.rst_prolog)
|
prepend_prolog(content, self.config.rst_prolog)
|
||||||
append_epilog(content, self.config.rst_epilog)
|
append_epilog(content, self.config.rst_epilog)
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app: "Sphinx") -> Dict[str, Any]:
|
||||||
# type: (Sphinx) -> Dict[str, Any]
|
|
||||||
app.add_source_parser(RSTParser)
|
app.add_source_parser(RSTParser)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
Reference in New Issue
Block a user