Merge pull request #3571 from tk0miya/refactor_init_builder

Refactor initialization process of builder
This commit is contained in:
Takeshi KOMIYA
2017-03-22 09:50:31 +09:00
committed by GitHub
7 changed files with 52 additions and 21 deletions

View File

@@ -40,6 +40,7 @@ Incompatible changes
support for multiple TeX engines. Only interface from ``color`` or
``xcolor`` packages should be used by extensions of Sphinx latex writer.
(refs #3550)
* ``Builder.env`` is not filled at instantiation
Features removed
----------------

View File

@@ -122,7 +122,6 @@ class Sphinx(object):
self._additional_source_parsers = {} # type: Dict[unicode, Parser]
self._setting_up_extension = ['?'] # type: List[unicode]
self.domains = {} # type: Dict[unicode, Type[Domain]]
self.buildername = buildername
self.builderclasses = {} # type: Dict[unicode, Type[Builder]]
self.builder = None # type: Builder
self.env = None # type: BuildEnvironment
@@ -241,6 +240,8 @@ class Sphinx(object):
logger.warning(_('primary_domain %r not found, ignored.'),
self.config.primary_domain)
# create the builder
self.builder = self.create_builder(buildername)
# check all configuration values for permissible types
self.config.check_types()
# set up source_parsers
@@ -248,7 +249,7 @@ class Sphinx(object):
# set up the build environment
self._init_env(freshenv)
# set up the builder
self._init_builder(self.buildername)
self._init_builder()
# set up the enumerable nodes
self._init_enumerable_nodes()
@@ -290,7 +291,7 @@ class Sphinx(object):
# type: (bool) -> None
if freshenv:
self.env = BuildEnvironment(self)
self.env.find_files(self.config, self.buildername)
self.env.find_files(self.config, self.builder)
for domain in self.domains.keys():
self.env.domains[domain] = self.domains[domain](self.env)
else:
@@ -310,8 +311,8 @@ class Sphinx(object):
logger.info(_('failed: %s'), err)
self._init_env(freshenv=True)
def _init_builder(self, buildername):
# type: (unicode) -> None
def create_builder(self, buildername):
# type: (unicode) -> Builder
if buildername is None:
logger.info(_('No builder selected, using default: html'))
buildername = 'html'
@@ -319,7 +320,12 @@ class Sphinx(object):
raise SphinxError(_('Builder name %s not registered') % buildername)
builderclass = self.builderclasses[buildername]
self.builder = builderclass(self)
return builderclass(self)
def _init_builder(self):
# type: () -> None
self.builder.set_environment(self.env)
self.builder.init()
self.emit('builder-inited')
def _init_enumerable_nodes(self):
@@ -327,6 +333,13 @@ class Sphinx(object):
for node, settings in iteritems(self.enumerable_nodes):
self.env.get_domain('std').enumerable_nodes[node] = settings # type: ignore
@property
def buildername(self):
# type: () -> unicode
warnings.warn('app.buildername is deprecated. Please use app.builder.name instead',
RemovedInSphinx17Warning)
return self.builder.name
# ---- main "build" method -------------------------------------------------
def build(self, force_all=False, filenames=None):

View File

@@ -57,12 +57,11 @@ class Builder(object):
versioning_compare = False
# allow parallel write_doc() calls
allow_parallel = False
# support translation
use_message_catalog = True
def __init__(self, app):
# type: (Sphinx) -> None
self.env = app.env # type: BuildEnvironment
self.env.set_versioning_method(self.versioning_method,
self.versioning_compare)
self.srcdir = app.srcdir
self.confdir = app.confdir
self.outdir = app.outdir
@@ -71,6 +70,7 @@ class Builder(object):
os.makedirs(self.doctreedir)
self.app = app # type: Sphinx
self.env = None # type: BuildEnvironment
self.warn = app.warn # type: Callable
self.info = app.info # type: Callable
self.config = app.config # type: Config
@@ -97,7 +97,12 @@ class Builder(object):
# load default translator class
self.translator_class = app._translators.get(self.name)
self.init()
def set_environment(self, env):
# type: (BuildEnvironment) -> None
"""Store BuildEnvironment object."""
self.env = env
self.env.set_versioning_method(self.versioning_method,
self.versioning_compare)
# helper methods
def init(self):
@@ -146,6 +151,11 @@ class Builder(object):
"""
raise NotImplementedError
def get_asset_paths(self):
# type: () -> List[unicode]
"""Return list of paths for assets (ex. templates, CSS, etc.)."""
return []
supported_image_types = [] # type: List[unicode]
def post_process_images(self, doctree):

View File

@@ -112,16 +112,15 @@ class I18nBuilder(Builder):
"""
name = 'i18n'
versioning_method = 'text'
versioning_compare = None # be set by `gettext_uuid`
def __init__(self, app):
# type: (Sphinx) -> None
self.versioning_compare = app.env.config.gettext_uuid
super(I18nBuilder, self).__init__(app)
versioning_compare = None # type: bool
# be set by `gettext_uuid`
use_message_catalog = False
def init(self):
# type: () -> None
Builder.init(self)
self.env.set_versioning_method(self.versioning_method,
self.env.config.gettext_uuid)
self.tags = I18nTags()
self.catalogs = defaultdict(Catalog) # type: defaultdict[unicode, Catalog]

View File

@@ -264,6 +264,10 @@ class StandaloneHTMLBuilder(Builder):
# source doesn't exist anymore
pass
def get_asset_paths(self):
# type: () -> List[unicode]
return self.config.html_extra_path
def render_partial(self, node):
# type: (nodes.Nodes) -> Dict[unicode, unicode]
"""Utility: Render a lone doctree node."""

View File

@@ -405,15 +405,15 @@ class BuildEnvironment(object):
enc_rel_fn = rel_fn.encode(sys.getfilesystemencoding())
return rel_fn, path.abspath(path.join(self.srcdir, enc_rel_fn))
def find_files(self, config, buildername):
# type: (Config, unicode) -> None
def find_files(self, config, builder):
# type: (Config, Builder) -> None
"""Find all source files in the source dir and put them in
self.found_docs.
"""
matchers = compile_matchers(
config.exclude_patterns[:] +
config.templates_path +
config.html_extra_path +
builder.get_asset_paths() +
['**/_sources', '.#*', '**/.#*', '*.lproj/**']
)
self.found_docs = set()
@@ -430,7 +430,7 @@ class BuildEnvironment(object):
# is set for the doc source and the mo file, it is processed again from
# the reading phase when mo is updated. In the future, we would like to
# move i18n process into the writing phase, and remove these lines.
if buildername != 'gettext':
if builder.use_message_catalog:
# add catalog mo file dependency
for docname in self.found_docs:
catalog_files = find_catalog_files(
@@ -522,7 +522,7 @@ class BuildEnvironment(object):
# the source and doctree directories may have been relocated
self.srcdir = srcdir
self.doctreedir = doctreedir
self.find_files(config, self.app.buildername)
self.find_files(config, self.app.builder)
self.config = config
# this cache also needs to be updated every time

View File

@@ -45,6 +45,8 @@ def test_images():
tree = env.get_doctree('images')
htmlbuilder = StandaloneHTMLBuilder(app)
htmlbuilder.set_environment(app.env)
htmlbuilder.init()
htmlbuilder.imgpath = 'dummy'
htmlbuilder.post_process_images(tree)
assert set(htmlbuilder.images.keys()) == \
@@ -54,6 +56,8 @@ def test_images():
set(['img.png', 'img1.png', 'simg.png', 'svgimg.svg', 'img.foo.png'])
latexbuilder = LaTeXBuilder(app)
latexbuilder.set_environment(app.env)
latexbuilder.init()
latexbuilder.post_process_images(tree)
assert set(latexbuilder.images.keys()) == \
set(['subdir/img.png', 'subdir/simg.png', 'img.png', 'img.pdf',