summaryrefslogtreecommitdiff
path: root/sphinx/application.py
diff options
context:
space:
mode:
Diffstat (limited to 'sphinx/application.py')
-rw-r--r--sphinx/application.py132
1 files changed, 42 insertions, 90 deletions
diff --git a/sphinx/application.py b/sphinx/application.py
index d23d97fbd..9195f11af 100644
--- a/sphinx/application.py
+++ b/sphinx/application.py
@@ -19,7 +19,7 @@ import posixpath
from os import path
from collections import deque
-from six import iteritems
+from six import iteritems, itervalues
from six.moves import cStringIO
from docutils import nodes
@@ -29,20 +29,18 @@ import sphinx
from sphinx import package_dir, locale
from sphinx.config import Config
from sphinx.errors import ConfigError, ExtensionError, VersionRequirementError
-from sphinx.deprecation import RemovedInSphinx17Warning, RemovedInSphinx20Warning
+from sphinx.deprecation import RemovedInSphinx20Warning
from sphinx.environment import BuildEnvironment
from sphinx.events import EventManager
from sphinx.extension import verify_required_extensions
-from sphinx.io import SphinxStandaloneReader
from sphinx.locale import __
from sphinx.registry import SphinxComponentRegistry
from sphinx.util import pycompat # noqa: F401
from sphinx.util import import_object
from sphinx.util import logging
-from sphinx.util import status_iterator, old_status_iterator, display_chunk
from sphinx.util.tags import Tags
from sphinx.util.osutil import ENOENT, ensuredir
-from sphinx.util.console import bold, darkgreen # type: ignore
+from sphinx.util.console import bold # type: ignore
from sphinx.util.docutils import is_html5_writer_available, directive_helper
from sphinx.util.i18n import find_catalog_source_files
@@ -55,12 +53,13 @@ if False:
from sphinx.domains import Domain, Index # NOQA
from sphinx.environment.collectors import EnvironmentCollector # NOQA
from sphinx.extension import Extension # NOQA
+ from sphinx.roles import XRefRole # NOQA
from sphinx.theming import Theme # NOQA
+ from sphinx.util.typing import RoleFunction # NOQA
builtin_extensions = (
'sphinx.builders.applehelp',
'sphinx.builders.changes',
- 'sphinx.builders.epub2',
'sphinx.builders.epub3',
'sphinx.builders.devhelp',
'sphinx.builders.dummy',
@@ -85,6 +84,7 @@ builtin_extensions = (
'sphinx.directives.code',
'sphinx.directives.other',
'sphinx.directives.patches',
+ 'sphinx.io',
'sphinx.parsers',
'sphinx.roles',
'sphinx.transforms.post_transforms',
@@ -121,7 +121,6 @@ class Sphinx(object):
self.env = None # type: BuildEnvironment
self.registry = SphinxComponentRegistry()
self.enumerable_nodes = {} # type: Dict[nodes.Node, Tuple[unicode, Callable]] # NOQA
- self.post_transforms = [] # type: List[Transform]
self.html_themes = {} # type: Dict[unicode, unicode]
self.srcdir = srcdir
@@ -316,13 +315,6 @@ class Sphinx(object):
for node, settings in iteritems(self.enumerable_nodes):
self.env.get_domain('std').enumerable_nodes[node] = settings # type: ignore
- @property
- def buildername(self):
- # type: () -> unicode
- warnings.warn('app.buildername is deprecated. Please use app.builder.name instead',
- RemovedInSphinx17Warning)
- return self.builder.name
-
# ---- main "build" method -------------------------------------------------
def build(self, force_all=False, filenames=None):
@@ -341,9 +333,9 @@ class Sphinx(object):
status = (self.statuscode == 0 and
__('succeeded') or __('finished with problems'))
if self._warncount:
- logger.info(bold(__('build %s, %s warning%s.') %
- (status, self._warncount,
- self._warncount != 1 and 's' or '')))
+ logger.info(bold(__('build %s, %s warning.',
+ 'build %s, %s warnings.', self._warncount) %
+ (status, self._warncount)))
else:
logger.info(bold(__('build %s.') % status))
except Exception as err:
@@ -358,31 +350,15 @@ class Sphinx(object):
self.builder.cleanup()
# ---- logging handling ----------------------------------------------------
- def warn(self, message, location=None, prefix=None,
- type=None, subtype=None, colorfunc=None):
- # type: (unicode, unicode, unicode, unicode, unicode, Callable) -> None
+ def warn(self, message, location=None, type=None, subtype=None):
+ # type: (unicode, unicode, unicode, unicode) -> None
"""Emit a warning.
If *location* is given, it should either be a tuple of (docname, lineno)
or a string describing the location of the warning as well as possible.
- *prefix* usually should not be changed.
-
*type* and *subtype* are used to suppress warnings with :confval:`suppress_warnings`.
-
- .. note::
-
- For warnings emitted during parsing, you should use
- :meth:`.BuildEnvironment.warn` since that will collect all
- warnings during parsing for later output.
"""
- if prefix:
- warnings.warn('prefix option of warn() is now deprecated.',
- RemovedInSphinx17Warning)
- if colorfunc:
- warnings.warn('colorfunc option of warn() is now deprecated.',
- RemovedInSphinx17Warning)
-
warnings.warn('app.warning() is now deprecated. Use sphinx.util.logging instead.',
RemovedInSphinx20Warning)
logger.warning(message, type=type, subtype=subtype, location=location)
@@ -419,34 +395,6 @@ class Sphinx(object):
RemovedInSphinx20Warning)
logger.debug(message, *args, **kwargs)
- def _display_chunk(chunk):
- # type: (Any) -> unicode
- warnings.warn('app._display_chunk() is now deprecated. '
- 'Use sphinx.util.display_chunk() instead.',
- RemovedInSphinx17Warning)
- return display_chunk(chunk)
-
- def old_status_iterator(self, iterable, summary, colorfunc=darkgreen,
- stringify_func=display_chunk):
- # type: (Iterable, unicode, Callable, Callable[[Any], unicode]) -> Iterator
- warnings.warn('app.old_status_iterator() is now deprecated. '
- 'Use sphinx.util.status_iterator() instead.',
- RemovedInSphinx17Warning)
- for item in old_status_iterator(iterable, summary,
- color="darkgreen", stringify_func=stringify_func):
- yield item
-
- # new version with progress info
- def status_iterator(self, iterable, summary, colorfunc=darkgreen, length=0,
- stringify_func=_display_chunk):
- # type: (Iterable, unicode, Callable, int, Callable[[Any], unicode]) -> Iterable
- warnings.warn('app.status_iterator() is now deprecated. '
- 'Use sphinx.util.status_iterator() instead.',
- RemovedInSphinx17Warning)
- for item in status_iterator(iterable, summary, length=length, verbosity=self.verbosity,
- color="darkgreen", stringify_func=stringify_func):
- yield item
-
# ---- general extensibility interface -------------------------------------
def setup_extension(self, extname):
@@ -496,7 +444,6 @@ class Sphinx(object):
def add_builder(self, builder):
# type: (Type[Builder]) -> None
- logger.debug('[app] adding builder: %r', builder)
self.registry.add_builder(builder)
def add_config_value(self, name, default, rebuild, types=()):
@@ -516,7 +463,6 @@ class Sphinx(object):
def set_translator(self, name, translator_class):
# type: (unicode, Type[nodes.NodeVisitor]) -> None
- logger.info(bold(__('Change of translator for the %s builder.') % name))
self.registry.add_translator(name, translator_class)
def add_node(self, node, **kwds):
@@ -568,13 +514,6 @@ class Sphinx(object):
self.enumerable_nodes[node] = (figtype, title_getter)
self.add_node(node, **kwds)
- def _directive_helper(self, obj, has_content=None, argument_spec=None, **option_spec):
- # type: (Any, bool, Tuple[int, int, bool], Any) -> Any
- warnings.warn('_directive_helper() is now deprecated. '
- 'Please use sphinx.util.docutils.directive_helper() instead.',
- RemovedInSphinx17Warning)
- return directive_helper(obj, has_content, argument_spec, **option_spec)
-
def add_directive(self, name, obj, content=None, arguments=None, **options):
# type: (unicode, Any, bool, Tuple[int, int, bool], Any) -> None
logger.debug('[app] adding directive: %r',
@@ -612,39 +551,30 @@ class Sphinx(object):
def add_domain(self, domain):
# type: (Type[Domain]) -> None
- logger.debug('[app] adding domain: %r', domain)
self.registry.add_domain(domain)
def override_domain(self, domain):
# type: (Type[Domain]) -> None
- logger.debug('[app] overriding domain: %r', domain)
self.registry.override_domain(domain)
def add_directive_to_domain(self, domain, name, obj,
has_content=None, argument_spec=None, **option_spec):
# type: (unicode, unicode, Any, bool, Any, Any) -> None
- logger.debug('[app] adding directive to domain: %r',
- (domain, name, obj, has_content, argument_spec, option_spec))
self.registry.add_directive_to_domain(domain, name, obj,
has_content, argument_spec, **option_spec)
def add_role_to_domain(self, domain, name, role):
- # type: (unicode, unicode, Any) -> None
- logger.debug('[app] adding role to domain: %r', (domain, name, role))
+ # type: (unicode, unicode, Union[RoleFunction, XRefRole]) -> None
self.registry.add_role_to_domain(domain, name, role)
def add_index_to_domain(self, domain, index):
# type: (unicode, Type[Index]) -> None
- logger.debug('[app] adding index to domain: %r', (domain, index))
self.registry.add_index_to_domain(domain, index)
def add_object_type(self, directivename, rolename, indextemplate='',
parse_node=None, ref_nodeclass=None, objname='',
doc_field_types=[]):
# type: (unicode, unicode, unicode, Callable, nodes.Node, unicode, List) -> None
- logger.debug('[app] adding object type: %r',
- (directivename, rolename, indextemplate, parse_node,
- ref_nodeclass, objname, doc_field_types))
self.registry.add_object_type(directivename, rolename, indextemplate, parse_node,
ref_nodeclass, objname, doc_field_types)
@@ -661,21 +591,16 @@ class Sphinx(object):
def add_crossref_type(self, directivename, rolename, indextemplate='',
ref_nodeclass=None, objname=''):
# type: (unicode, unicode, unicode, nodes.Node, unicode) -> None
- logger.debug('[app] adding crossref type: %r',
- (directivename, rolename, indextemplate, ref_nodeclass,
- objname))
self.registry.add_crossref_type(directivename, rolename,
indextemplate, ref_nodeclass, objname)
def add_transform(self, transform):
# type: (Type[Transform]) -> None
- logger.debug('[app] adding transform: %r', transform)
- SphinxStandaloneReader.transforms.append(transform)
+ self.registry.add_transform(transform)
def add_post_transform(self, transform):
# type: (Type[Transform]) -> None
- logger.debug('[app] adding post transform: %r', transform)
- self.post_transforms.append(transform)
+ self.registry.add_post_transform(transform)
def add_javascript(self, filename):
# type: (unicode) -> None
@@ -736,7 +661,6 @@ class Sphinx(object):
def add_source_parser(self, suffix, parser):
# type: (unicode, Parser) -> None
- logger.debug('[app] adding search source_parser: %r, %r', suffix, parser)
self.registry.add_source_parser(suffix, parser)
def add_env_collector(self, collector):
@@ -749,6 +673,34 @@ class Sphinx(object):
logger.debug('[app] adding HTML theme: %r, %r', name, theme_path)
self.html_themes[name] = theme_path
+ # ---- other methods -------------------------------------------------
+ def is_parallel_allowed(self, typ):
+ # type: (unicode) -> bool
+ """Check parallel processing is allowed or not.
+
+ ``typ`` is a type of processing; ``'read'`` or ``'write'``.
+ """
+ if typ == 'read':
+ attrname = 'parallel_read_safe'
+ elif typ == 'write':
+ attrname = 'parallel_write_safe'
+ else:
+ raise ValueError('parallel type %s is not supported' % typ)
+
+ for ext in itervalues(self.extensions):
+ allowed = getattr(ext, attrname, None)
+ if allowed is None:
+ logger.warning(__("the %s extension does not declare if it is safe "
+ "for parallel %sing, assuming it isn't - please "
+ "ask the extension author to check and make it "
+ "explicit"), ext.name, typ)
+ logger.warning('doing serial %s', typ)
+ return False
+ elif not allowed:
+ return False
+
+ return True
+
class TemplateBridge(object):
"""