diff options
Diffstat (limited to 'sphinx/application.py')
-rw-r--r-- | sphinx/application.py | 81 |
1 files changed, 10 insertions, 71 deletions
diff --git a/sphinx/application.py b/sphinx/application.py index eeaa954eb..fc8e0aa86 100644 --- a/sphinx/application.py +++ b/sphinx/application.py @@ -17,7 +17,6 @@ import sys import types import warnings import posixpath -import traceback from os import path from collections import deque @@ -38,6 +37,7 @@ from sphinx.domains.std import GenericObject, Target, StandardDomain from sphinx.deprecation import RemovedInSphinx17Warning, RemovedInSphinx20Warning from sphinx.environment import BuildEnvironment from sphinx.events import EventManager +from sphinx.extension import load_extension, verify_required_extensions from sphinx.io import SphinxStandaloneReader from sphinx.locale import _ from sphinx.roles import XRefRole @@ -59,6 +59,7 @@ if False: from sphinx.builders import Builder # NOQA from sphinx.domains import Domain, Index # NOQA from sphinx.environment.collectors import EnvironmentCollector # NOQA + from sphinx.extension import Extension # NOQA builtin_extensions = ( 'sphinx.builders.applehelp', @@ -97,15 +98,14 @@ builtin_extensions = ( 'sphinx.environment.collectors.title', 'sphinx.environment.collectors.toctree', 'sphinx.environment.collectors.indexentries', + # Strictly, alabaster theme is not a builtin extension, + # but it is loaded automatically to use it as default theme. + 'alabaster', ) # type: Tuple[unicode, ...] CONFIG_FILENAME = 'conf.py' ENV_PICKLE_FILENAME = 'environment.pickle' -# list of deprecated extensions. Keys are extension name. -# Values are Sphinx version that merge the extension. -EXTENSION_BLACKLIST = {"sphinxjp.themecore": "1.2"} # type: Dict[unicode, unicode] - logger = logging.getLogger(__name__) @@ -117,8 +117,7 @@ class Sphinx(object): parallel=0): # type: (unicode, unicode, unicode, unicode, unicode, Dict, IO, IO, bool, bool, List[unicode], int, int) -> None # NOQA self.verbosity = verbosity - self._extensions = {} # type: Dict[unicode, Any] - self._extension_metadata = {} # type: Dict[unicode, Dict[unicode, Any]] + self.extensions = {} # type: Dict[unicode, Extension] self._additional_source_parsers = {} # type: Dict[unicode, Parser] self._setting_up_extension = ['?'] # type: List[unicode] self.domains = {} # type: Dict[unicode, Type[Domain]] @@ -195,12 +194,6 @@ class Sphinx(object): for extension in builtin_extensions: self.setup_extension(extension) - # extension loading support for alabaster theme - # self.config.html_theme is not set from conf.py at here - # for now, sphinx always load a 'alabaster' extension. - if 'alabaster' not in self.config.extensions: - self.config.extensions.append('alabaster') - # load all user-given extension modules for extension in self.config.extensions: self.setup_extension(extension) @@ -221,19 +214,7 @@ class Sphinx(object): self.config.init_values() # check extension versions if requested - if self.config.needs_extensions: - for extname, needs_ver in self.config.needs_extensions.items(): - if extname not in self._extensions: - logger.warning(_('needs_extensions config value specifies a ' - 'version requirement for extension %s, but it is ' - 'not loaded'), extname) - continue - has_ver = self._extension_metadata[extname]['version'] - if has_ver == 'unknown version' or needs_ver > has_ver: - raise VersionRequirementError( - _('This project needs the extension %s at least in ' - 'version %s and therefore cannot be built with the ' - 'loaded version (%s).') % (extname, needs_ver, has_ver)) + verify_required_extensions(self, self.config.needs_extensions) # check primary_domain if requested if self.config.primary_domain and self.config.primary_domain not in self.domains: @@ -466,53 +447,11 @@ class Sphinx(object): # ---- general extensibility interface ------------------------------------- - def setup_extension(self, extension): + def setup_extension(self, extname): # type: (unicode) -> None """Import and setup a Sphinx extension module. No-op if called twice.""" - logger.debug('[app] setting up extension: %r', extension) - if extension in self._extensions: - return - if extension in EXTENSION_BLACKLIST: - logger.warning(_('the extension %r was already merged with Sphinx since ' - 'version %s; this extension is ignored.'), - extension, EXTENSION_BLACKLIST[extension]) - return - self._setting_up_extension.append(extension) - try: - mod = __import__(extension, None, None, ['setup']) - except ImportError as err: - logger.verbose(_('Original exception:\n') + traceback.format_exc()) - raise ExtensionError(_('Could not import extension %s') % extension, - err) - if not hasattr(mod, 'setup'): - logger.warning(_('extension %r has no setup() function; is it really ' - 'a Sphinx extension module?'), extension) - ext_meta = None - else: - try: - ext_meta = mod.setup(self) - except VersionRequirementError as err: - # add the extension name to the version required - raise VersionRequirementError( - _('The %s extension used by this project needs at least ' - 'Sphinx v%s; it therefore cannot be built with this ' - 'version.') % (extension, err)) - if ext_meta is None: - ext_meta = {} - # special-case for compatibility - if extension == 'rst2pdf.pdfbuilder': - ext_meta = {'parallel_read_safe': True} - try: - if not ext_meta.get('version'): - ext_meta['version'] = 'unknown version' - except Exception: - logger.warning(_('extension %r returned an unsupported object from ' - 'its setup() function; it should return None or a ' - 'metadata dictionary'), extension) - ext_meta = {'version': 'unknown version'} - self._extensions[extension] = mod - self._extension_metadata[extension] = ext_meta - self._setting_up_extension.pop() + logger.debug('[app] setting up extension: %r', extname) + load_extension(self, extname) def require_sphinx(self, version): # type: (unicode) -> None |