refactor: SphinxStandaloneReader should not hold an application object

This commit is contained in:
Takeshi KOMIYA 2019-03-09 16:35:47 +09:00
parent 63757596b1
commit 21cd1c2ef5
5 changed files with 60 additions and 20 deletions

View File

@ -10,6 +10,9 @@ Incompatible changes
Deprecated Deprecated
---------- ----------
* ``sphinx.io.SphinxStandaloneReader.app``
* ``sphinx.io.SphinxStandaloneReader.env``
Features added Features added
-------------- --------------

View File

@ -26,6 +26,16 @@ The following is a list of deprecated interfaces.
- (will be) Removed - (will be) Removed
- Alternatives - Alternatives
* - ``sphinx.io.SphinxStandaloneReader.app``
- 2.3
- 4.0
- ``sphinx.io.SphinxStandaloneReader.setup()``
* - ``sphinx.io.SphinxStandaloneReader.env``
- 2.3
- 4.0
- ``sphinx.io.SphinxStandaloneReader.setup()``
* - ``sphinx.domains.math.MathDomain.add_equation()`` * - ``sphinx.domains.math.MathDomain.add_equation()``
- 2.2 - 2.2
- 4.0 - 4.0

View File

@ -19,7 +19,7 @@ from docutils.statemachine import StringList, string2lines
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 RemovedInSphinx30Warning from sphinx.deprecation import RemovedInSphinx30Warning, RemovedInSphinx40Warning
from sphinx.transforms import ( from sphinx.transforms import (
AutoIndexUpgrader, DoctreeReadEvent, FigureAligner, SphinxTransformer AutoIndexUpgrader, DoctreeReadEvent, FigureAligner, SphinxTransformer
) )
@ -58,12 +58,35 @@ class SphinxBaseReader(standalone.Reader):
transforms = [] # type: List[Type[Transform]] transforms = [] # type: List[Type[Transform]]
def __init__(self, app, *args, **kwargs): def __init__(self, *args, **kwargs):
# type: (Sphinx, Any, Any) -> None # type: (Any, Any) -> None
self.app = app from sphinx.application import Sphinx
self.env = app.env if len(args) > 0 and isinstance(args[0], Sphinx):
self._app = args[0]
self._env = self._app.env
args = args[1:]
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
@property
def app(self):
# type: () -> Sphinx
warnings.warn('SphinxBaseReader.app is deprecated.',
RemovedInSphinx40Warning, stacklevel=2)
return self._app
@property
def env(self):
# type: () -> BuildEnvironment
warnings.warn('SphinxBaseReader.env is deprecated.',
RemovedInSphinx40Warning, stacklevel=2)
return self._env
def setup(self, app):
# type: (Sphinx) -> None
self._app = app # hold application object only for compatibility
self._env = app.env
def get_transforms(self): def get_transforms(self):
# type: () -> List[Type[Transform]] # type: () -> List[Type[Transform]]
transforms = super().get_transforms() + self.transforms transforms = super().get_transforms() + self.transforms
@ -85,7 +108,7 @@ class SphinxBaseReader(standalone.Reader):
# substitute transformer # substitute transformer
document.transformer = SphinxTransformer(document) document.transformer = SphinxTransformer(document)
document.transformer.set_environment(self.env) document.transformer.set_environment(self.settings.env)
# substitute reporter # substitute reporter
reporter = document.reporter reporter = document.reporter
@ -99,10 +122,10 @@ class SphinxStandaloneReader(SphinxBaseReader):
A basic document reader for Sphinx. A basic document reader for Sphinx.
""" """
def __init__(self, app, *args, **kwargs): def setup(self, app):
# type: (Sphinx, Any, Any) -> None # type: (Sphinx) -> None
self.transforms = self.transforms + app.registry.get_transforms() self.transforms = self.transforms + app.registry.get_transforms()
super().__init__(app, *args, **kwargs) super().setup(app)
def read(self, source, parser, settings): def read(self, source, parser, settings):
# type: (Input, Parser, Values) -> nodes.document # type: (Input, Parser, Values) -> nodes.document
@ -110,18 +133,18 @@ class SphinxStandaloneReader(SphinxBaseReader):
if not self.parser: if not self.parser:
self.parser = parser self.parser = parser
self.settings = settings self.settings = settings
self.input = self.read_source() self.input = self.read_source(settings.env)
self.parse() self.parse()
return self.document return self.document
def read_source(self): def read_source(self, env):
# type: () -> 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()
# emit "source-read" event # emit "source-read" event
arg = [content] arg = [content]
self.app.emit('source-read', self.env.docname, arg) env.events.emit('source-read', env.docname, arg)
return arg[0] return arg[0]
@ -134,8 +157,10 @@ 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 __init__(self, app, *args, **kwargs): def setup(self, app):
# type: (Sphinx, Any, Any) -> None # type: (Sphinx) -> None
super().setup(app)
self.transforms = self.transforms + app.registry.get_transforms() self.transforms = self.transforms + app.registry.get_transforms()
unused = [PreserveTranslatableMessages, Locale, RemoveTranslatableInline, unused = [PreserveTranslatableMessages, Locale, RemoveTranslatableInline,
AutoIndexUpgrader, FigureAligner, SphinxDomains, DoctreeReadEvent, AutoIndexUpgrader, FigureAligner, SphinxDomains, DoctreeReadEvent,
@ -144,8 +169,6 @@ class SphinxI18nReader(SphinxBaseReader):
if transform in self.transforms: if transform in self.transforms:
self.transforms.remove(transform) self.transforms.remove(transform)
super().__init__(app, *args, **kwargs)
def set_lineno_for_reporter(self, lineno): def set_lineno_for_reporter(self, lineno):
# type: (int) -> None # type: (int) -> None
"""Stores the source line number of original text.""" """Stores the source line number of original text."""
@ -290,7 +313,8 @@ def read_doc(app, env, filename):
error_handler = UnicodeDecodeErrorHandler(env.docname) error_handler = UnicodeDecodeErrorHandler(env.docname)
codecs.register_error('sphinx', error_handler) # type: ignore codecs.register_error('sphinx', error_handler) # type: ignore
reader = SphinxStandaloneReader(app) reader = SphinxStandaloneReader()
reader.setup(app)
filetype = get_filetype(app.config.source_suffix, filename) filetype = get_filetype(app.config.source_suffix, filename)
parser = app.registry.create_source_parser(app, filetype) parser = app.registry.create_source_parser(app, filetype)
if parser.__class__.__name__ == 'CommonMarkParser' and parser.settings_spec == (): if parser.__class__.__name__ == 'CommonMarkParser' and parser.settings_spec == ():

View File

@ -21,11 +21,13 @@ def parse(app: Sphinx, text: str, docname: str = 'index') -> nodes.document:
"""Parse a string as reStructuredText with Sphinx application.""" """Parse a string as reStructuredText with Sphinx application."""
try: try:
app.env.temp_data['docname'] = docname app.env.temp_data['docname'] = docname
reader = SphinxStandaloneReader()
reader.setup(app)
parser = RSTParser() parser = RSTParser()
parser.set_application(app) parser.set_application(app)
with sphinx_domains(app.env): with sphinx_domains(app.env):
return publish_doctree(text, path.join(app.srcdir, docname + '.rst'), return publish_doctree(text, path.join(app.srcdir, docname + '.rst'),
reader=SphinxStandaloneReader(app), reader=reader,
parser=parser, parser=parser,
settings_overrides={'env': app.env, settings_overrides={'env': app.env,
'gettext_compact': True}) 'gettext_compact': True})

View File

@ -53,7 +53,8 @@ def publish_msgstr(app, source, source_path, source_line, config, settings):
:rtype: docutils.nodes.document :rtype: docutils.nodes.document
""" """
from sphinx.io import SphinxI18nReader from sphinx.io import SphinxI18nReader
reader = SphinxI18nReader(app) reader = SphinxI18nReader()
reader.setup(app)
parser = app.registry.create_source_parser(app, 'restructuredtext') parser = app.registry.create_source_parser(app, 'restructuredtext')
doc = reader.read( doc = reader.read(
source=StringInput(source=source, source=StringInput(source=source,