Merge pull request #4486 from tk0miya/4460_env_version_of_extensions

Close #4460: extensions should return the version of data structure as metadata
This commit is contained in:
Takeshi KOMIYA 2018-01-28 21:15:07 +09:00 committed by GitHub
commit 0f4a4b2ae9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 57 additions and 8 deletions

View File

@ -7,6 +7,10 @@ Dependencies
Incompatible changes
--------------------
* #4460: extensions which stores any data to environment should return the
version of its env data structure as metadata. In detail, please see
:ref:`ext-metadata`.
Deprecated
----------

View File

@ -52,6 +52,8 @@ Note that it is still necessary to register the builder using
.. _entry points: https://setuptools.readthedocs.io/en/latest/setuptools.html#dynamic-discovery-of-services-and-plugins
.. _ext-metadata:
Extension metadata
------------------
@ -63,6 +65,11 @@ as metadata of the extension. Metadata keys currently recognized are:
* ``'version'``: a string that identifies the extension version. It is used for
extension version requirement checking (see :confval:`needs_extensions`) and
informational purposes. If not given, ``"unknown version"`` is substituted.
* ``'env_version'``: an integer that identifies the version of env data
structure if the extension stores any data to environment. It is used to
detect the data structure has been changed from last build. The extensions
have to increment the version when data structure has changed. If not given,
Sphinx considers the extension does not stores any data to environment.
* ``'parallel_read_safe'``: a boolean that specifies if parallel reading of
source files can be used when the extension is loaded. It defaults to
``False``, i.e. you have to explicitly specify your extension to be

View File

@ -304,6 +304,9 @@ class Sphinx(object):
logger.info(bold(__('loading pickled environment... ')), nonl=True)
filename = path.join(self.doctreedir, ENV_PICKLE_FILENAME)
self.env = BuildEnvironment.frompickle(filename, self)
needed, reason = self.env.need_refresh(self)
if needed:
raise IOError(reason)
self.env.domains = {}
for domain in self.registry.create_domains(self.env):
# this can raise if the data version doesn't fit

View File

@ -330,6 +330,7 @@ def setup(app):
return {
'version': 'builtin',
'env_version': 1,
'parallel_read_safe': True,
'parallel_write_safe': True,
}

View File

@ -6099,6 +6099,7 @@ def setup(app):
return {
'version': 'builtin',
'env_version': 1,
'parallel_read_safe': True,
'parallel_write_safe': True,
}

View File

@ -415,6 +415,7 @@ def setup(app):
return {
'version': 'builtin',
'env_version': 1,
'parallel_read_safe': True,
'parallel_write_safe': True,
}

View File

@ -912,6 +912,7 @@ def setup(app):
return {
'version': 'builtin',
'env_version': 1,
'parallel_read_safe': True,
'parallel_write_safe': True,
}

View File

@ -182,6 +182,7 @@ def setup(app):
return {
'version': 'builtin',
'env_version': 1,
'parallel_read_safe': True,
'parallel_write_safe': True,
}

View File

@ -980,6 +980,7 @@ def setup(app):
return {
'version': 'builtin',
'env_version': 1,
'parallel_read_safe': True,
'parallel_write_safe': True,
}

View File

@ -107,13 +107,9 @@ class BuildEnvironment(object):
# This can happen for example when the pickle is from a
# different version of Sphinx.
raise IOError(exc)
if env.version != ENV_VERSION:
raise IOError('build environment version not current')
if app:
env.app = app
env.config.values = app.config.values
if env.srcdir != app.srcdir:
raise IOError('source directory has changed')
return env
@classmethod
@ -187,7 +183,7 @@ class BuildEnvironment(object):
self._warnfunc = None # type: Callable
# this is to invalidate old pickles
self.version = ENV_VERSION
self.version = app.registry.get_envversion(app)
# All "docnames" here are /-separated and relative and exclude
# the source suffix.
@ -304,6 +300,19 @@ class BuildEnvironment(object):
"""Like :meth:`warn`, but with source information taken from *node*."""
self._warnfunc(msg, '%s:%s' % get_source_line(node), **kwargs)
def need_refresh(self, app):
# type: (Sphinx) -> Tuple[bool, unicode]
"""Check refresh environment is needed.
If needed, this method returns the reason for refresh.
"""
if self.version != app.registry.get_envversion(app):
return True, 'build environment version not current'
elif self.srcdir != app.srcdir:
return True, 'source directory has changed'
else:
return False, None
def clear_doc(self, docname):
# type: (unicode) -> None
"""Remove all traces of a source file in the inventory."""

View File

@ -347,7 +347,11 @@ def setup(app):
app.add_config_value('intersphinx_timeout', None, False)
app.connect('missing-reference', missing_reference)
app.connect('builder-inited', load_mappings)
return {'version': sphinx.__display_version__, 'parallel_read_safe': True}
return {
'version': sphinx.__display_version__,
'env_version': 1,
'parallel_read_safe': True
}
def debug(argv):

View File

@ -258,4 +258,8 @@ def setup(app):
app.connect('doctree-resolved', process_todo_nodes)
app.connect('env-purge-doc', purge_todos)
app.connect('env-merge-info', merge_info)
return {'version': sphinx.__display_version__, 'parallel_read_safe': True}
return {
'version': sphinx.__display_version__,
'env_version': 1,
'parallel_read_safe': True
}

View File

@ -241,4 +241,8 @@ def setup(app):
app.connect('missing-reference', missing_reference)
# app.add_config_value('viewcode_include_modules', [], 'env')
# app.add_config_value('viewcode_exclude_modules', [], 'env')
return {'version': sphinx.__display_version__, 'parallel_read_safe': True}
return {
'version': sphinx.__display_version__,
'env_version': 1,
'parallel_read_safe': True
}

View File

@ -339,3 +339,11 @@ class SphinxComponentRegistry(object):
app.extensions[extname] = Extension(extname, mod, **metadata)
app._setting_up_extension.pop()
def get_envversion(self, app):
# type: (Sphinx) -> Dict[unicode, unicode]
from sphinx.environment import ENV_VERSION
envversion = {ext.name: ext.metadata['env_version'] for ext in app.extensions.values()
if ext.metadata.get('env_version')}
envversion['sphinx'] = ENV_VERSION
return envversion