Add support for extensions to declare their version as a string returned from setup().

This commit is contained in:
Georg Brandl 2014-09-03 16:27:15 +02:00
parent 7207b614b6
commit b6594d18d1
5 changed files with 19 additions and 3 deletions

View File

@ -26,6 +26,9 @@ Features added
* Add support for docutils 0.12 * Add support for docutils 0.12
* Added ``sphinx.ext.napoleon`` extension for NumPy and Google style docstring * Added ``sphinx.ext.napoleon`` extension for NumPy and Google style docstring
support. support.
* Added support for extension versions (a string returned by ``setup()``, these
can be shown in the traceback log files). In the future this might also be
used for version checking.
* PR#214: Added stemming support for 14 languages, so that the built-in document * PR#214: Added stemming support for 14 languages, so that the built-in document
search can now handle these. Thanks to Shibukawa Yoshiki. search can now handle these. Thanks to Shibukawa Yoshiki.
* PR#202: Allow "." and "~" prefixed references in ``:param:`` doc fields * PR#202: Allow "." and "~" prefixed references in ``:param:`` doc fields

View File

@ -18,6 +18,11 @@ imports this module and executes its ``setup()`` function, which in turn
notifies Sphinx of everything the extension offers -- see the extension tutorial notifies Sphinx of everything the extension offers -- see the extension tutorial
for examples. for examples.
.. versionadded:: 1.3
The ``setup()`` function can return a string, this is treated by Sphinx as
the version of the extension and used for informational purposes such as the
traceback file when an exception occurs.
The configuration file itself can be treated as an extension if it contains a The configuration file itself can be treated as an extension if it contains a
``setup()`` function. All other extensions to load must be listed in the ``setup()`` function. All other extensions to load must be listed in the
:confval:`extensions` configuration value. :confval:`extensions` configuration value.

View File

@ -162,6 +162,8 @@ new Python module called :file:`todo.py` and add the setup function::
app.connect('doctree-resolved', process_todo_nodes) app.connect('doctree-resolved', process_todo_nodes)
app.connect('env-purge-doc', purge_todos) app.connect('env-purge-doc', purge_todos)
return '0.1' # identifies the version of our extension
The calls in this function refer to classes and functions not yet written. What The calls in this function refer to classes and functions not yet written. What
the individual calls do is the following: the individual calls do is the following:

View File

@ -71,6 +71,7 @@ class Sphinx(object):
self.verbosity = verbosity self.verbosity = verbosity
self.next_listener_id = 0 self.next_listener_id = 0
self._extensions = {} self._extensions = {}
self._extension_versions = {}
self._listeners = {} self._listeners = {}
self.domains = BUILTIN_DOMAINS.copy() self.domains = BUILTIN_DOMAINS.copy()
self.builderclasses = BUILTIN_BUILDERS.copy() self.builderclasses = BUILTIN_BUILDERS.copy()
@ -345,16 +346,20 @@ class Sphinx(object):
if not hasattr(mod, 'setup'): if not hasattr(mod, 'setup'):
self.warn('extension %r has no setup() function; is it really ' self.warn('extension %r has no setup() function; is it really '
'a Sphinx extension module?' % extension) 'a Sphinx extension module?' % extension)
version = None
else: else:
try: try:
mod.setup(self) version = mod.setup(self)
except VersionRequirementError as err: except VersionRequirementError as err:
# add the extension name to the version required # add the extension name to the version required
raise VersionRequirementError( raise VersionRequirementError(
'The %s extension used by this project needs at least ' 'The %s extension used by this project needs at least '
'Sphinx v%s; it therefore cannot be built with this ' 'Sphinx v%s; it therefore cannot be built with this '
'version.' % (extension, err)) 'version.' % (extension, err))
if version is None:
version = 'unknown version'
self._extensions[extension] = mod self._extensions[extension] = mod
self._extension_versions[extension] = version
def require_sphinx(self, version): def require_sphinx(self, version):
# check the Sphinx version if requested # check the Sphinx version if requested

View File

@ -191,8 +191,9 @@ def save_traceback(app):
jinja2.__version__)).encode('utf-8')) jinja2.__version__)).encode('utf-8'))
if app is not None: if app is not None:
for extname, extmod in iteritems(app._extensions): for extname, extmod in iteritems(app._extensions):
os.write(fd, ('# %s from %s\n' % ( os.write(fd, ('# %s (%s) from %s\n' % (
extname, getattr(extmod, '__file__', 'unknown')) extname, app._extension_versions[extname],
getattr(extmod, '__file__', 'unknown'))
).encode('utf-8')) ).encode('utf-8'))
os.write(fd, exc.encode('utf-8')) os.write(fd, exc.encode('utf-8'))
os.close(fd) os.close(fd)