Reimplement IndexEntriesManager as a collector

This commit is contained in:
Takeshi KOMIYA 2017-01-11 00:55:57 +09:00
parent e2c7b1db42
commit 851172b13b
5 changed files with 24 additions and 118 deletions

View File

@ -109,6 +109,7 @@ builtin_extensions = (
'sphinx.environment.collectors.metadata',
'sphinx.environment.collectors.title',
'sphinx.environment.collectors.toctree',
'sphinx.environment.collectors.indexentries',
) # type: Tuple[unicode, ...]
CONFIG_FILENAME = 'conf.py'
@ -308,7 +309,6 @@ class Sphinx(object):
logger.info(bold('loading pickled environment... '), nonl=True)
self.env = BuildEnvironment.frompickle(
self.srcdir, self.config, path.join(self.doctreedir, ENV_PICKLE_FILENAME))
self.env.init_managers()
self.env.domains = {}
for domain in self.domains.keys():
# this can raise if the data version doesn't fit

View File

@ -20,7 +20,7 @@ import warnings
from os import path
from collections import defaultdict
from six import iteritems, itervalues, class_types, next
from six import itervalues, class_types, next
from six.moves import cPickle as pickle
from docutils import nodes
@ -49,7 +49,6 @@ from sphinx.versioning import add_uids, merge_doctrees
from sphinx.deprecation import RemovedInSphinx20Warning
from sphinx.environment.adapters.indexentries import IndexEntries
from sphinx.environment.adapters.toctree import TocTree
from sphinx.environment.managers.indexentries import IndexEntries as IndexEntriesManager
if False:
# For type annotation
@ -58,7 +57,6 @@ if False:
from sphinx.builders import Builder # NOQA
from sphinx.config import Config # NOQA
from sphinx.domains import Domain # NOQA
from sphinx.environment.managers import EnvironmentManager # NOQA
logger = logging.getLogger(__name__)
@ -125,7 +123,6 @@ class BuildEnvironment(object):
del self.config.values
domains = self.domains
del self.domains
managers = self.detach_managers()
# remove potentially pickling-problematic values from config
for key, val in list(vars(self.config).items()):
if key.startswith('_') or \
@ -136,7 +133,6 @@ class BuildEnvironment(object):
with open(filename, 'wb') as picklefile:
pickle.dump(self, picklefile, pickle.HIGHEST_PROTOCOL)
# reset attributes
self.attach_managers(managers)
self.domains = domains
self.config.values = values
@ -241,31 +237,6 @@ class BuildEnvironment(object):
# attributes of "any" cross references
self.ref_context = {} # type: Dict[unicode, Any]
self.managers = {} # type: Dict[unicode, EnvironmentManager]
self.init_managers()
def init_managers(self):
# type: () -> None
managers = {}
manager_class = None # type: Type[EnvironmentManager]
for manager_class in [IndexEntriesManager]: # type: ignore
managers[manager_class.name] = manager_class(self)
self.attach_managers(managers)
def attach_managers(self, managers):
# type: (Dict[unicode, EnvironmentManager]) -> None
for name, manager in iteritems(managers):
self.managers[name] = manager
manager.attach(self)
def detach_managers(self):
# type: () -> Dict[unicode, EnvironmentManager]
managers = self.managers
self.managers = {}
for _, manager in iteritems(managers):
manager.detach(self)
return managers
def set_warnfunc(self, func):
# type: (Callable) -> None
warnings.warn('env.set_warnfunc() is now deprecated. Use sphinx.util.logging instead.',
@ -317,9 +288,6 @@ class BuildEnvironment(object):
new = [change for change in changes if change[1] != docname]
changes[:] = new
for manager in itervalues(self.managers):
manager.clear_doc(docname)
for domain in self.domains.values():
domain.clear_doc(docname)
@ -340,8 +308,6 @@ class BuildEnvironment(object):
self.versionchanges.setdefault(version, []).extend(
change for change in changes if change[1] in docnames)
for manager in itervalues(self.managers):
manager.merge_other(docnames, other)
for domainname, domain in self.domains.items():
domain.merge_domaindata(docnames, other.domaindata[domainname])
app.emit('env-merge-info', self, docnames, other)
@ -647,9 +613,7 @@ class BuildEnvironment(object):
def check_dependents(self, app, already):
# type: (Sphinx, Set[unicode]) -> Iterator[unicode]
to_rewrite = []
for manager in itervalues(self.managers):
to_rewrite.extend(manager.get_updated_docs())
to_rewrite = [] # type: List[unicode]
for docnames in app.emit('env-get-updated', self):
to_rewrite.extend(docnames)
for docname in set(to_rewrite):
@ -722,8 +686,6 @@ class BuildEnvironment(object):
doctree = pub.document
# post-processing
for manager in itervalues(self.managers):
manager.process_doc(docname, doctree)
for domain in itervalues(self.domains):
domain.process_doc(self, docname, doctree)

View File

@ -1,9 +1,9 @@
# -*- coding: utf-8 -*-
"""
sphinx.environment.managers.indexentries
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sphinx.environment.collectors.indexentries
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Index entries manager for sphinx.environment.
Index entries collector for sphinx.environment.
:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
@ -11,36 +11,33 @@
from sphinx import addnodes
from sphinx.util import split_index_msg, logging
from sphinx.environment.managers import EnvironmentManager
from sphinx.environment.collectors import EnvironmentCollector
if False:
# For type annotation
from docutils import nodes # NOQA
from sphinx.applicatin import Sphinx # NOQA
from sphinx.environment import BuildEnvironment # NOQA
logger = logging.getLogger(__name__)
class IndexEntries(EnvironmentManager):
class IndexEntriesCollector(EnvironmentCollector):
name = 'indices'
def __init__(self, env):
# type: (BuildEnvironment) -> None
super(IndexEntries, self).__init__(env)
self.data = env.indexentries
def clear_doc(self, app, env, docname):
# type: (Sphinx, BuildEnvironment, unicode) -> None
env.indexentries.pop(docname, None)
def clear_doc(self, docname):
# type: (unicode) -> None
self.data.pop(docname, None)
def merge_other(self, docnames, other):
# type: (List[unicode], BuildEnvironment) -> None
def merge_other(self, app, env, docnames, other):
# type: (Sphinx, BuildEnvironment, Set[unicode], BuildEnvironment) -> None
for docname in docnames:
self.data[docname] = other.indexentries[docname]
env.indexentries[docname] = other.indexentries[docname]
def process_doc(self, docname, doctree):
# type: (unicode, nodes.Node) -> None
entries = self.data[docname] = []
def process_doc(self, app, doctree):
# type: (Sphinx, nodes.Node) -> None
docname = app.env.docname
entries = app.env.indexentries[docname] = []
for node in doctree.traverse(addnodes.index):
try:
for entry in node['entries']:
@ -56,6 +53,7 @@ class IndexEntries(EnvironmentManager):
else:
entries.append(entry + (None,))
def get_updated_docs(self):
# type: () -> List[unicode]
return []
def setup(app):
# type: (Sphinx) -> None
app.add_env_collector(IndexEntriesCollector)

View File

@ -1,54 +0,0 @@
# -*- coding: utf-8 -*-
"""
sphinx.environment.managers
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Manager components for sphinx.environment.
:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
if False:
# For type annotation
from typing import Any # NOQA
from docutils import nodes # NOQA
from sphinx.environment import BuildEnvironment # NOQA
class EnvironmentManager(object):
"""Base class for sphinx.environment managers."""
name = None # type: unicode
env = None # type: BuildEnvironment
def __init__(self, env):
# type: (BuildEnvironment) -> None
self.env = env
def attach(self, env):
# type: (BuildEnvironment) -> None
self.env = env
if self.name:
setattr(env, self.name, self)
def detach(self, env):
# type: (BuildEnvironment) -> None
self.env = None
if self.name:
delattr(env, self.name)
def clear_doc(self, docname):
# type: (unicode) -> None
raise NotImplementedError
def merge_other(self, docnames, other):
# type: (List[unicode], Any) -> None
raise NotImplementedError
def process_doc(self, docname, doctree):
# type: (unicode, nodes.Node) -> None
raise NotImplementedError
def get_updated_docs(self):
# type: () -> List[unicode]
raise NotImplementedError

View File

@ -30,10 +30,10 @@ ENV_WARNINGS = """\
WARNING: Explicit markup ends without a blank line; unexpected unindent.
%(root)s/index.rst:\\d+: WARNING: Encoding 'utf-8-sig' used for reading included \
file u'%(root)s/wrongenc.inc' seems to be wrong, try giving an :encoding: option
%(root)s/index.rst:\\d+: WARNING: invalid single index entry u''
%(root)s/index.rst:\\d+: WARNING: image file not readable: foo.png
%(root)s/index.rst:\\d+: WARNING: nonlocal image URI found: http://www.python.org/logo.png
%(root)s/index.rst:\\d+: WARNING: download file not readable: %(root)s/nonexisting.png
%(root)s/index.rst:\\d+: WARNING: invalid single index entry u''
%(root)s/undecodable.rst:\\d+: WARNING: undecodable source characters, replacing \
with "\\?": b?'here: >>>(\\\\|/)xbb<<<((\\\\|/)r)?'
"""