mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Closes #851: Recognize and warn about circular toctrees, instead of running into recursion errors.
This commit is contained in:
3
CHANGES
3
CHANGES
@@ -24,6 +24,9 @@ Release 1.1.3 (in development)
|
|||||||
|
|
||||||
* #862: Fix handling of ``-D`` and ``-A`` options on Python 3.
|
* #862: Fix handling of ``-D`` and ``-A`` options on Python 3.
|
||||||
|
|
||||||
|
* #851: Recognize and warn about circular toctrees, instead of running
|
||||||
|
into recursion errors.
|
||||||
|
|
||||||
|
|
||||||
Release 1.1.2 (Nov 1, 2011) -- 1.1.1 is a silly version number anyway!
|
Release 1.1.2 (Nov 1, 2011) -- 1.1.1 is a silly version number anyway!
|
||||||
======================================================================
|
======================================================================
|
||||||
|
|||||||
@@ -1313,12 +1313,14 @@ class BuildEnvironment:
|
|||||||
subnode['iscurrent'] = True
|
subnode['iscurrent'] = True
|
||||||
subnode = subnode.parent
|
subnode = subnode.parent
|
||||||
|
|
||||||
def _entries_from_toctree(toctreenode, separate=False, subtree=False):
|
def _entries_from_toctree(toctreenode, parents,
|
||||||
|
separate=False, subtree=False):
|
||||||
"""Return TOC entries for a toctree node."""
|
"""Return TOC entries for a toctree node."""
|
||||||
refs = [(e[0], str(e[1])) for e in toctreenode['entries']]
|
refs = [(e[0], str(e[1])) for e in toctreenode['entries']]
|
||||||
entries = []
|
entries = []
|
||||||
for (title, ref) in refs:
|
for (title, ref) in refs:
|
||||||
try:
|
try:
|
||||||
|
refdoc = None
|
||||||
if url_re.match(ref):
|
if url_re.match(ref):
|
||||||
reference = nodes.reference('', '', internal=False,
|
reference = nodes.reference('', '', internal=False,
|
||||||
refuri=ref, anchorname='',
|
refuri=ref, anchorname='',
|
||||||
@@ -1341,6 +1343,12 @@ class BuildEnvironment:
|
|||||||
# don't show subitems
|
# don't show subitems
|
||||||
toc = nodes.bullet_list('', item)
|
toc = nodes.bullet_list('', item)
|
||||||
else:
|
else:
|
||||||
|
if ref in parents:
|
||||||
|
self.warn(ref, 'circular toctree references '
|
||||||
|
'detected, ignoring: %s <- %s' %
|
||||||
|
(ref, ' <- '.join(parents)))
|
||||||
|
continue
|
||||||
|
refdoc = ref
|
||||||
toc = self.tocs[ref].deepcopy()
|
toc = self.tocs[ref].deepcopy()
|
||||||
self.process_only_nodes(toc, builder, ref)
|
self.process_only_nodes(toc, builder, ref)
|
||||||
if title and toc.children and len(toc.children) == 1:
|
if title and toc.children and len(toc.children) == 1:
|
||||||
@@ -1376,7 +1384,8 @@ class BuildEnvironment:
|
|||||||
if not (toctreenode.get('hidden', False)
|
if not (toctreenode.get('hidden', False)
|
||||||
and not includehidden):
|
and not includehidden):
|
||||||
i = toctreenode.parent.index(toctreenode) + 1
|
i = toctreenode.parent.index(toctreenode) + 1
|
||||||
for item in _entries_from_toctree(toctreenode,
|
for item in _entries_from_toctree(
|
||||||
|
toctreenode, [refdoc] + parents,
|
||||||
subtree=True):
|
subtree=True):
|
||||||
toctreenode.parent.insert(i, item)
|
toctreenode.parent.insert(i, item)
|
||||||
i += 1
|
i += 1
|
||||||
@@ -1398,7 +1407,7 @@ class BuildEnvironment:
|
|||||||
# NOTE: previously, this was separate=True, but that leads to artificial
|
# NOTE: previously, this was separate=True, but that leads to artificial
|
||||||
# separation when two or more toctree entries form a logical unit, so
|
# separation when two or more toctree entries form a logical unit, so
|
||||||
# separating mode is no longer used -- it's kept here for history's sake
|
# separating mode is no longer used -- it's kept here for history's sake
|
||||||
tocentries = _entries_from_toctree(toctree, separate=False)
|
tocentries = _entries_from_toctree(toctree, [], separate=False)
|
||||||
if not tocentries:
|
if not tocentries:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -1686,7 +1695,11 @@ class BuildEnvironment:
|
|||||||
def collect_relations(self):
|
def collect_relations(self):
|
||||||
relations = {}
|
relations = {}
|
||||||
getinc = self.toctree_includes.get
|
getinc = self.toctree_includes.get
|
||||||
def collect(parents, docname, previous, next):
|
def collect(parents, parents_set, docname, previous, next):
|
||||||
|
# circular relationship?
|
||||||
|
if docname in parents_set:
|
||||||
|
# we will warn about this in resolve_toctree()
|
||||||
|
return
|
||||||
includes = getinc(docname)
|
includes = getinc(docname)
|
||||||
# previous
|
# previous
|
||||||
if not previous:
|
if not previous:
|
||||||
@@ -1723,9 +1736,10 @@ class BuildEnvironment:
|
|||||||
for subindex, args in enumerate(izip(includes,
|
for subindex, args in enumerate(izip(includes,
|
||||||
[None] + includes,
|
[None] + includes,
|
||||||
includes[1:] + [None])):
|
includes[1:] + [None])):
|
||||||
collect([(docname, subindex)] + parents, *args)
|
collect([(docname, subindex)] + parents,
|
||||||
|
parents_set.union([docname]), *args)
|
||||||
relations[docname] = [parents[0][0], previous, next]
|
relations[docname] = [parents[0][0], previous, next]
|
||||||
collect([(None, 0)], self.config.master_doc, None, None)
|
collect([(None, 0)], set(), self.config.master_doc, None, None)
|
||||||
return relations
|
return relations
|
||||||
|
|
||||||
def check_consistency(self):
|
def check_consistency(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user