diff options
author | Takeshi KOMIYA <i.tkomiya@gmail.com> | 2017-03-22 09:57:25 +0900 |
---|---|---|
committer | Takeshi KOMIYA <i.tkomiya@gmail.com> | 2017-03-23 22:50:11 +0900 |
commit | 9025297faa9176657a1faca72e07c0a0468deb5c (patch) | |
tree | 4881c8ed2b06ac02a0fb72ea0d93d3d4affafa75 | |
parent | 064a0da8c3c4c252f1e5146e8cf287b972378e0f (diff) | |
download | sphinx-git-9025297faa9176657a1faca72e07c0a0468deb5c.tar.gz |
Add Extension class
-rw-r--r-- | sphinx/application.py | 4 | ||||
-rw-r--r-- | sphinx/builders/__init__.py | 8 | ||||
-rw-r--r-- | sphinx/environment/__init__.py | 29 | ||||
-rw-r--r-- | sphinx/environment/adapters/indexentries.py | 4 | ||||
-rw-r--r-- | sphinx/extensions.py | 25 | ||||
-rw-r--r-- | sphinx/util/__init__.py | 11 |
6 files changed, 43 insertions, 38 deletions
diff --git a/sphinx/application.py b/sphinx/application.py index 92176487e..7b6b0788e 100644 --- a/sphinx/application.py +++ b/sphinx/application.py @@ -58,6 +58,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.extensions import Extension # NOQA builtin_extensions = ( 'sphinx.builders.applehelp', @@ -112,8 +113,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]] diff --git a/sphinx/builders/__init__.py b/sphinx/builders/__init__.py index f7593020a..adb3a3b8a 100644 --- a/sphinx/builders/__init__.py +++ b/sphinx/builders/__init__.py @@ -17,6 +17,7 @@ try: except ImportError: multiprocessing = None +from six import itervalues from docutils import nodes from sphinx.util import i18n, path_stabilize, logging, status_iterator @@ -337,11 +338,10 @@ class Builder(object): self.parallel_ok = False if parallel_available and self.app.parallel > 1 and self.allow_parallel: self.parallel_ok = True - for extname, md in self.app._extension_metadata.items(): - par_ok = md.get('parallel_write_safe', True) - if not par_ok: + for extension in itervalues(self.app.extensions): + if not extension.parallel_write_safe: logger.warning('the %s extension is not safe for parallel ' - 'writing, doing serial write', extname) + 'writing, doing serial write', extension.name) self.parallel_ok = False break diff --git a/sphinx/environment/__init__.py b/sphinx/environment/__init__.py index 014850f7f..45dfae8f5 100644 --- a/sphinx/environment/__init__.py +++ b/sphinx/environment/__init__.py @@ -43,6 +43,7 @@ from sphinx.util.matching import compile_matchers from sphinx.util.parallel import ParallelTasks, parallel_available, make_chunks from sphinx.util.websupport import is_commentable from sphinx.errors import SphinxError, ExtensionError +from sphinx.locale import _ from sphinx.transforms import SphinxTransformer from sphinx.versioning import add_uids, merge_doctrees from sphinx.deprecation import RemovedInSphinx17Warning, RemovedInSphinx20Warning @@ -559,22 +560,20 @@ class BuildEnvironment(object): # check if we should do parallel or serial read par_ok = False if parallel_available and len(docnames) > 5 and self.app.parallel > 1: - par_ok = True - for extname, md in self.app._extension_metadata.items(): - ext_ok = md.get('parallel_read_safe') - if ext_ok: - continue - if ext_ok is None: - logger.warning('the %s extension does not declare if it ' - 'is safe for parallel reading, assuming it ' - 'isn\'t - please ask the extension author to ' - 'check and make it explicit', extname) + for ext in itervalues(self.app.extensions): + if ext.parallel_read_safe is None: + logger.warning(_('the %s extension does not declare if it is safe ' + 'for parallel reading, assuming it isn\'t - please ' + 'ask the extension author to check and make it ' + 'explicit'), ext.name) logger.warning('doing serial read') - else: - logger.warning('the %s extension is not safe for parallel ' - 'reading, doing serial read', extname) - par_ok = False - break + break + elif ext.parallel_read_safe is False: + break + else: + # all extensions support parallel-read + par_ok = True + if par_ok: self._read_parallel(docnames, self.app, nproc=self.app.parallel) else: diff --git a/sphinx/environment/adapters/indexentries.py b/sphinx/environment/adapters/indexentries.py index 31ec58301..4eb1f8a32 100644 --- a/sphinx/environment/adapters/indexentries.py +++ b/sphinx/environment/adapters/indexentries.py @@ -13,10 +13,10 @@ import bisect import unicodedata from itertools import groupby -from six import text_type +from six import text_type, iteritems from sphinx.locale import _ -from sphinx.util import iteritems, split_into, logging +from sphinx.util import split_into, logging if False: # For type annotation diff --git a/sphinx/extensions.py b/sphinx/extensions.py index d51b6760d..8e929a48b 100644 --- a/sphinx/extensions.py +++ b/sphinx/extensions.py @@ -33,11 +33,20 @@ EXTENSION_BLACKLIST = { } # type: Dict[unicode, unicode] +class Extension(object): + def __init__(self, name, module, **kwargs): + self.name = name + self.module = module + self.version = kwargs.pop('version', 'unknown version') + self.parallel_read_safe = kwargs.pop('parallel_read_safe', None) + self.parallel_write_safe = kwargs.pop('parallel_read_safe', True) + self.metadata = kwargs + + def load(app, extname): # type: (Sphinx, unicode) -> None """Load a Sphinx extension.""" - if extname in app._extensions: - # alread loaded + if extname in app.extensions: # alread loaded return if extname in EXTENSION_BLACKLIST: logger.warning(_('the extension %r was already merged with Sphinx since ' @@ -78,9 +87,7 @@ def load(app, extname): 'its setup() function; it should return None or a ' 'metadata dictionary'), extname) - metadata.setdefault('version', 'unknown version') - app._extensions[extname] = mod - app._extension_metadata[extname] = metadata + app.extensions[extname] = Extension(extname, mod, **metadata) app._setting_up_extension.pop() @@ -91,15 +98,15 @@ def confirm(app, requirements): return for extname, reqversion in iteritems(requirements): - if extname not in app._extensions: + extension = app.extensions.get(extname) + if extension is None: logger.warning(_('needs_extensions config value specifies a ' 'version requirement for extension %s, but it is ' 'not loaded'), extname) continue - extversion = app._extension_metadata[extname].get('version') - if extversion == 'unknown version' or reqversion > extversion: + if extension.version == 'unknown version' or reqversion > extension.version: raise VersionRequirementError(_('This project needs the extension %s at least in ' 'version %s and therefore cannot be built with ' 'the loaded version (%s).') % - (extname, reqversion, extversion)) + (extname, reqversion, extension.version)) diff --git a/sphinx/util/__init__.py b/sphinx/util/__init__.py index a3823546d..adf526e06 100644 --- a/sphinx/util/__init__.py +++ b/sphinx/util/__init__.py @@ -22,7 +22,7 @@ from os import path from codecs import BOM_UTF8 from collections import deque -from six import iteritems, text_type, binary_type +from six import text_type, binary_type from six.moves import range from six.moves.urllib.parse import urlsplit, urlunsplit, quote_plus, parse_qsl, urlencode from docutils.utils import relative_path @@ -227,14 +227,13 @@ def save_traceback(app): jinja2.__version__, # type: ignore last_msgs)).encode('utf-8')) if app is not None: - for extname, extmod in iteritems(app._extensions): - modfile = getattr(extmod, '__file__', 'unknown') + for ext in app.extensions: + modfile = getattr(ext.module, '__file__', 'unknown') if isinstance(modfile, bytes): modfile = modfile.decode(fs_encoding, 'replace') - version = app._extension_metadata[extname]['version'] - if version != 'builtin': + if ext.version != 'builtin': os.write(fd, ('# %s (%s) from %s\n' % - (extname, version, modfile)).encode('utf-8')) + (ext.name, ext.version, modfile)).encode('utf-8')) os.write(fd, exc_format.encode('utf-8')) os.close(fd) return path |