mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Find third-party builders by entry point
A builder is uniquely identified by its name, which can be used as an entry point in the 'sphinx.builders' entry point group. This obviates the need to register the builder as an extension. The built-in builders are still loaded as before. New third-party builders should provide an entry point in their setup.py: entry_points={ 'sphinx.builders': [ 'mybuilder = mypackage.mymodule:MyBuilder', ], } Like before, builders should define a setup(app) function in the 'mypackage.module' module to define configuration variables etc. It is no longer necessary to register the builder using Sphinx.add_builder(). Existing builders can still be loaded the traditional way, by including their module name in the extensions list in conf.py.
This commit is contained in:
parent
1c4915f904
commit
405ef96d2a
@ -22,6 +22,34 @@ 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.
|
||||
|
||||
Discovery of builders by entry point
|
||||
------------------------------------
|
||||
|
||||
.. versionadded:: 1.6
|
||||
|
||||
:term:`Builder` extensions can be discovered by means of `entry points`_ so
|
||||
they do not have to be listed in the :confval:`extensions` configuration value.
|
||||
|
||||
Builder extensions need to define an entry point in the ``sphinx.builders``
|
||||
group. The name of the entry point needs to be set to the name of the builder,
|
||||
which is the name passed to the :option:`sphinx-build -b` option. Here is an
|
||||
example of how an entry point for 'mybuilder' can be defined in ``setup.py``::
|
||||
|
||||
setup(
|
||||
# ...
|
||||
entry_points={
|
||||
'sphinx.builders': [
|
||||
'mybuilder = mypackage.mymodule:MyBuilder',
|
||||
],
|
||||
}
|
||||
)
|
||||
|
||||
It is no longer strictly necessary to register the builder using
|
||||
:meth:`~.Sphinx.add_builder` in the extension's ``setup()`` function, but it is
|
||||
recommended to not remove this in order to ensure backward compatiblity.
|
||||
|
||||
.. _entry points: https://setuptools.readthedocs.io/en/latest/setuptools.html#dynamic-discovery-of-services-and-plugins
|
||||
|
||||
Extension metadata
|
||||
------------------
|
||||
|
||||
|
@ -26,6 +26,7 @@ from six.moves import cStringIO
|
||||
from docutils import nodes
|
||||
from docutils.parsers.rst import convert_directive_function, \
|
||||
directives, roles
|
||||
from pkg_resources import iter_entry_points
|
||||
|
||||
import sphinx
|
||||
from sphinx import package_dir, locale
|
||||
@ -298,10 +299,19 @@ class Sphinx(object):
|
||||
if buildername is None:
|
||||
logger.info(_('No builder selected, using default: html'))
|
||||
buildername = 'html'
|
||||
if buildername not in self.builderclasses:
|
||||
raise SphinxError(_('Builder name %s not registered') % buildername)
|
||||
|
||||
builderclass = self.builderclasses[buildername]
|
||||
if buildername in self.builderclasses:
|
||||
builderclass = self.builderclasses[buildername]
|
||||
else:
|
||||
entry_points = iter_entry_points('sphinx.builders', buildername)
|
||||
try:
|
||||
entry_point = next(entry_points)
|
||||
except StopIteration:
|
||||
raise SphinxError('Builder name %s not registered or available'
|
||||
' through entry point' % buildername)
|
||||
else:
|
||||
builderclass = entry_point.load()
|
||||
extension_module = sys.modules[builderclass.__module__]
|
||||
extension_module.setup(self)
|
||||
return builderclass(self)
|
||||
|
||||
def _init_builder(self):
|
||||
|
Loading…
Reference in New Issue
Block a user