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
* Added ``sphinx.ext.napoleon`` extension for NumPy and Google style docstring
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
search can now handle these. Thanks to Shibukawa Yoshiki.
* 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
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
``setup()`` function. All other extensions to load must be listed in the
: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('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 individual calls do is the following:

View File

@ -71,6 +71,7 @@ class Sphinx(object):
self.verbosity = verbosity
self.next_listener_id = 0
self._extensions = {}
self._extension_versions = {}
self._listeners = {}
self.domains = BUILTIN_DOMAINS.copy()
self.builderclasses = BUILTIN_BUILDERS.copy()
@ -345,16 +346,20 @@ class Sphinx(object):
if not hasattr(mod, 'setup'):
self.warn('extension %r has no setup() function; is it really '
'a Sphinx extension module?' % extension)
version = None
else:
try:
mod.setup(self)
version = 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 version is None:
version = 'unknown version'
self._extensions[extension] = mod
self._extension_versions[extension] = version
def require_sphinx(self, version):
# check the Sphinx version if requested

View File

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