diff options
| -rw-r--r-- | sphinx/application.py | 16 | ||||
| -rw-r--r-- | sphinx/domains.py | 20 | ||||
| -rw-r--r-- | sphinx/environment.py | 27 | ||||
| -rw-r--r-- | sphinx/util/__init__.py | 11 | ||||
| -rw-r--r-- | tests/root/desc.txt | 10 | ||||
| -rw-r--r-- | tests/test_env.py | 7 |
6 files changed, 60 insertions, 31 deletions
diff --git a/sphinx/application.py b/sphinx/application.py index e26d619e..3566bc50 100644 --- a/sphinx/application.py +++ b/sphinx/application.py @@ -107,11 +107,6 @@ class Sphinx(object): # now that we know all config values, collect them from conf.py self.config.init_values() - # intialize domains - self.domains = {} - for domain in all_domains.keys(): - self.domains[domain] = all_domains[domain]() - # set up translation infrastructure self._init_i18n() # set up the build environment @@ -144,20 +139,25 @@ class Sphinx(object): self.env = BuildEnvironment(self.srcdir, self.doctreedir, self.config) self.env.find_files(self.config) + for domain in all_domains.keys(): + self.env.domains[domain] = all_domains[domain](self.env) else: try: self.info(bold('loading pickled environment... '), nonl=True) self.env = BuildEnvironment.frompickle(self.config, path.join(self.doctreedir, ENV_PICKLE_FILENAME)) + self.env.domains = {} + for domain in all_domains.keys(): + # this can raise if the data version doesn't fit + self.env.domains[domain] = all_domains[domain](self.env) self.info('done') except Exception, err: if type(err) is IOError and err.errno == 2: self.info('not yet created') else: self.info('failed: %s' % err) - self.env = BuildEnvironment(self.srcdir, self.doctreedir, - self.config) - self.env.find_files(self.config) + return self._init_env(freshenv=True) + self.env.set_warnfunc(self.warn) def _init_builder(self, buildername): diff --git a/sphinx/domains.py b/sphinx/domains.py index f3389da1..66448111 100644 --- a/sphinx/domains.py +++ b/sphinx/domains.py @@ -11,6 +11,9 @@ """ import re +import string + +from docutils import nodes from sphinx import addnodes from sphinx.roles import XRefRole @@ -24,7 +27,18 @@ class Domain(object): roles = {} label = '' - def __init__(self): + # data value for a fresh environment + initial_data = { + + } + # data version + data_version = 0 + + def __init__(self, env): + self.env = env + self.data = env.domaindata.get(self.name, self.initial_data) + if 'version' in self.data and self.data['version'] < self.data_version: + raise IOError('data of %r domain out of date' % self.label) self._role_cache = {} self._directive_cache = {} @@ -35,6 +49,8 @@ class Domain(object): state['_directive_cache'] = {} return state + #def clear_doc + def role(self, name): """ Return a role adapter function that always gives the registered @@ -492,7 +508,7 @@ class CDesc(DescDirective): if part[0] in string.ascii_letters+'_' and \ part not in self.stopwords: pnode = addnodes.pending_xref( - '', reftype='ctype', reftarget=part, + '', refdomain='c', reftype='type', reftarget=part, modname=None, classname=None) pnode += tnode node += pnode diff --git a/sphinx/environment.py b/sphinx/environment.py index a5bf49eb..62d3875b 100644 --- a/sphinx/environment.py +++ b/sphinx/environment.py @@ -213,9 +213,9 @@ class BuildEnvironment: env = pickle.load(picklefile) finally: picklefile.close() - env.config.values = config.values if env.version != ENV_VERSION: raise IOError('env version not current') + env.config.values = config.values return env def topickle(self, filename): @@ -224,6 +224,8 @@ class BuildEnvironment: self.set_warnfunc(None) values = self.config.values del self.config.values + domains = self.domains + del self.domains # first write to a temporary file, so that if dumping fails, # the existing environment won't be overwritten picklefile = open(filename + '.tmp', 'wb') @@ -240,6 +242,7 @@ class BuildEnvironment: picklefile.close() movefile(filename + '.tmp', filename) # reset attributes + self.domains = domains self.config.values = values self.set_warnfunc(warnfunc) @@ -253,6 +256,9 @@ class BuildEnvironment: # the application object; only set while update() runs self.app = None + # all the registered domains, set by the application + self.domains = {} + # the docutils settings for building self.settings = default_settings.copy() self.settings['env'] = self @@ -291,6 +297,9 @@ class BuildEnvironment: self.glob_toctrees = set() # docnames that have :glob: toctrees self.numbered_toctrees = set() # docnames that have :numbered: toctrees + # domain-specific inventories + self.domaindata = {} # domainname -> object + # X-ref target inventory self.descrefs = {} # fullname -> docname, desctype self.modules = {} # modname -> docname, synopsis, @@ -600,14 +609,15 @@ class BuildEnvironment: return data # defaults to the global default, but can be re-set in a document - self.default_domain = app.domains.get(self.config.default_domain) + self.default_domain = self.domains.get(self.config.default_domain) # monkey-patch, so that domain directives take precedence def directive(directive_name, language_module, document): + directive_name = directive_name.lower() if ':' in directive_name: domain_name, directive_name = directive_name.split(':', 1) - if domain_name in app.domains: - domain = app.domains[domain_name] + if domain_name in self.domains: + domain = self.domains[domain_name] directive = domain.directive(directive_name) if directive is not None: return directive, [] @@ -620,10 +630,11 @@ class BuildEnvironment: directives.directive = directive def role(role_name, language_module, lineno, reporter): + role_name = role_name.lower() if ':' in role_name: domain_name, role_name = role_name.split(':', 1) - if domain_name in app.domains: - domain = app.domains[domain_name] + if domain_name in self.domains: + domain = self.domains[domain_name] role = domain.role(role_name) if role is not None: return role, [] @@ -1216,7 +1227,7 @@ class BuildEnvironment: if node.has_key('refdomain'): # let the domain try to resolve the reference try: - domain = builder.app.domains[node['refdomain']] + domain = self.domains[node['refdomain']] except KeyError: raise NoUri newnode = domain.resolve_xref(self, fromdocname, builder, @@ -1320,7 +1331,7 @@ class BuildEnvironment: # no new node found? try the missing-reference event if newnode is None: newnode = builder.app.emit_firstresult( - 'missing-reference', env, node, contnode) + 'missing-reference', self, node, contnode) except NoUri: newnode = contnode node.replace_self(newnode or contnode) diff --git a/sphinx/util/__init__.py b/sphinx/util/__init__.py index f8a14cac..c238fd47 100644 --- a/sphinx/util/__init__.py +++ b/sphinx/util/__init__.py @@ -438,6 +438,8 @@ def split_explicit_title(text): return False, text, text +from docutils import nodes + def make_refnode(builder, fromdocname, todocname, targetid, child, title=None): """Shortcut to create a reference node.""" node = nodes.reference('', '') @@ -481,8 +483,7 @@ def _new_traverse(self, condition=None, return self._old_traverse(condition, include_self, descend, siblings, ascend) -import docutils.nodes -docutils.nodes.Node._old_traverse = docutils.nodes.Node.traverse -docutils.nodes.Node._all_traverse = _all_traverse -docutils.nodes.Node._fast_traverse = _fast_traverse -docutils.nodes.Node.traverse = _new_traverse +nodes.Node._old_traverse = nodes.Node.traverse +nodes.Node._all_traverse = _all_traverse +nodes.Node._fast_traverse = _fast_traverse +nodes.Node.traverse = _new_traverse diff --git a/tests/root/desc.txt b/tests/root/desc.txt index d6915dc2..bdceafc0 100644 --- a/tests/root/desc.txt +++ b/tests/root/desc.txt @@ -43,15 +43,15 @@ Testing description units C items ======= -.. cfunction:: Sphinx_DoSomething() +.. c:function:: Sphinx_DoSomething() -.. cmember:: SphinxStruct.member +.. c:member:: SphinxStruct.member -.. cmacro:: SPHINX_USE_PYTHON +.. c:macro:: SPHINX_USE_PYTHON -.. ctype:: SphinxType +.. c:type:: SphinxType -.. cvar:: sphinx_global +.. c:var:: sphinx_global Testing references diff --git a/tests/test_env.py b/tests/test_env.py index a06656d6..d5f40f8c 100644 --- a/tests/test_env.py +++ b/tests/test_env.py @@ -21,7 +21,8 @@ warnings = [] def setup_module(): global app, env app = TestApp(srcdir='(temp)') - env = BuildEnvironment(app.srcdir, app.doctreedir, app.config) + env = app.env + #env = BuildEnvironment(app.srcdir, app.doctreedir, app.config) env.set_warnfunc(lambda *args: warnings.append(args)) def teardown_module(): @@ -51,7 +52,7 @@ def test_images(): tree = env.get_doctree('images') app._warning.reset() - htmlbuilder = StandaloneHTMLBuilder(app, env) + htmlbuilder = StandaloneHTMLBuilder(app) htmlbuilder.post_process_images(tree) assert "no matching candidate for image URI u'foo.*'" in \ app._warning.content[-1] @@ -61,7 +62,7 @@ def test_images(): set(['img.png', 'img1.png', 'simg.png', 'svgimg.svg']) app._warning.reset() - latexbuilder = LaTeXBuilder(app, env) + latexbuilder = LaTeXBuilder(app) latexbuilder.post_process_images(tree) assert "no matching candidate for image URI u'foo.*'" in \ app._warning.content[-1] |
