mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Fix #7301: Allow . and _ for node_id
In development of 3.0, Sphinx starts to obey to the rule of
"Identifier Normalization" of docutils. This extends it to allow
dots(".") and underscores("_") for node identifier.
It allows Sphinx to generate node identifier from source string as
possible as it is (bacause dots and underscores are usually used in
many programming langauges).
This change will keep not to break hyperlinks as possible.
This commit is contained in:
@@ -171,11 +171,11 @@ def test_resolve_xref_for_properties(app, status, warning):
|
||||
app.builder.build_all()
|
||||
|
||||
content = (app.outdir / 'module.html').read_text()
|
||||
assert ('Link to <a class="reference internal" href="#module-a-submodule-modtoplevel-prop"'
|
||||
assert ('Link to <a class="reference internal" href="#module_a.submodule.modtoplevel.prop"'
|
||||
' title="module_a.submodule.ModTopLevel.prop">'
|
||||
'<code class="xref py py-attr docutils literal notranslate"><span class="pre">'
|
||||
'prop</span> <span class="pre">attribute</span></code></a>' in content)
|
||||
assert ('Link to <a class="reference internal" href="#module-a-submodule-modtoplevel-prop"'
|
||||
assert ('Link to <a class="reference internal" href="#module_a.submodule.modtoplevel.prop"'
|
||||
' title="module_a.submodule.ModTopLevel.prop">'
|
||||
'<code class="xref py py-meth docutils literal notranslate"><span class="pre">'
|
||||
'prop</span> <span class="pre">method</span></code></a>' in content)
|
||||
@@ -194,18 +194,18 @@ def test_domain_py_find_obj(app, status, warning):
|
||||
assert (find_obj(None, None, 'NestedParentA', 'class') ==
|
||||
[('NestedParentA', ('roles', 'nestedparenta', 'class'))])
|
||||
assert (find_obj(None, None, 'NestedParentA.NestedChildA', 'class') ==
|
||||
[('NestedParentA.NestedChildA', ('roles', 'nestedparenta-nestedchilda', 'class'))])
|
||||
[('NestedParentA.NestedChildA', ('roles', 'nestedparenta.nestedchilda', 'class'))])
|
||||
assert (find_obj(None, 'NestedParentA', 'NestedChildA', 'class') ==
|
||||
[('NestedParentA.NestedChildA', ('roles', 'nestedparenta-nestedchilda', 'class'))])
|
||||
[('NestedParentA.NestedChildA', ('roles', 'nestedparenta.nestedchilda', 'class'))])
|
||||
assert (find_obj(None, None, 'NestedParentA.NestedChildA.subchild_1', 'meth') ==
|
||||
[('NestedParentA.NestedChildA.subchild_1',
|
||||
('roles', 'nestedparenta-nestedchilda-subchild-1', 'method'))])
|
||||
('roles', 'nestedparenta.nestedchilda.subchild_1', 'method'))])
|
||||
assert (find_obj(None, 'NestedParentA', 'NestedChildA.subchild_1', 'meth') ==
|
||||
[('NestedParentA.NestedChildA.subchild_1',
|
||||
('roles', 'nestedparenta-nestedchilda-subchild-1', 'method'))])
|
||||
('roles', 'nestedparenta.nestedchilda.subchild_1', 'method'))])
|
||||
assert (find_obj(None, 'NestedParentA.NestedChildA', 'subchild_1', 'meth') ==
|
||||
[('NestedParentA.NestedChildA.subchild_1',
|
||||
('roles', 'nestedparenta-nestedchilda-subchild-1', 'method'))])
|
||||
('roles', 'nestedparenta.nestedchilda.subchild_1', 'method'))])
|
||||
|
||||
|
||||
def test_get_full_qualified_name():
|
||||
@@ -483,61 +483,61 @@ def test_pymethod_options(app):
|
||||
|
||||
# method
|
||||
assert_node(doctree[1][1][0], addnodes.index,
|
||||
entries=[('single', 'meth1() (Class method)', 'class-meth1', '', None)])
|
||||
entries=[('single', 'meth1() (Class method)', 'class.meth1', '', None)])
|
||||
assert_node(doctree[1][1][1], ([desc_signature, ([desc_name, "meth1"],
|
||||
[desc_parameterlist, ()])],
|
||||
[desc_content, ()]))
|
||||
assert 'Class.meth1' in domain.objects
|
||||
assert domain.objects['Class.meth1'] == ('index', 'class-meth1', 'method')
|
||||
assert domain.objects['Class.meth1'] == ('index', 'class.meth1', 'method')
|
||||
|
||||
# :classmethod:
|
||||
assert_node(doctree[1][1][2], addnodes.index,
|
||||
entries=[('single', 'meth2() (Class class method)', 'class-meth2', '', None)])
|
||||
entries=[('single', 'meth2() (Class class method)', 'class.meth2', '', None)])
|
||||
assert_node(doctree[1][1][3], ([desc_signature, ([desc_annotation, "classmethod "],
|
||||
[desc_name, "meth2"],
|
||||
[desc_parameterlist, ()])],
|
||||
[desc_content, ()]))
|
||||
assert 'Class.meth2' in domain.objects
|
||||
assert domain.objects['Class.meth2'] == ('index', 'class-meth2', 'method')
|
||||
assert domain.objects['Class.meth2'] == ('index', 'class.meth2', 'method')
|
||||
|
||||
# :staticmethod:
|
||||
assert_node(doctree[1][1][4], addnodes.index,
|
||||
entries=[('single', 'meth3() (Class static method)', 'class-meth3', '', None)])
|
||||
entries=[('single', 'meth3() (Class static method)', 'class.meth3', '', None)])
|
||||
assert_node(doctree[1][1][5], ([desc_signature, ([desc_annotation, "static "],
|
||||
[desc_name, "meth3"],
|
||||
[desc_parameterlist, ()])],
|
||||
[desc_content, ()]))
|
||||
assert 'Class.meth3' in domain.objects
|
||||
assert domain.objects['Class.meth3'] == ('index', 'class-meth3', 'method')
|
||||
assert domain.objects['Class.meth3'] == ('index', 'class.meth3', 'method')
|
||||
|
||||
# :async:
|
||||
assert_node(doctree[1][1][6], addnodes.index,
|
||||
entries=[('single', 'meth4() (Class method)', 'class-meth4', '', None)])
|
||||
entries=[('single', 'meth4() (Class method)', 'class.meth4', '', None)])
|
||||
assert_node(doctree[1][1][7], ([desc_signature, ([desc_annotation, "async "],
|
||||
[desc_name, "meth4"],
|
||||
[desc_parameterlist, ()])],
|
||||
[desc_content, ()]))
|
||||
assert 'Class.meth4' in domain.objects
|
||||
assert domain.objects['Class.meth4'] == ('index', 'class-meth4', 'method')
|
||||
assert domain.objects['Class.meth4'] == ('index', 'class.meth4', 'method')
|
||||
|
||||
# :property:
|
||||
assert_node(doctree[1][1][8], addnodes.index,
|
||||
entries=[('single', 'meth5() (Class property)', 'class-meth5', '', None)])
|
||||
entries=[('single', 'meth5() (Class property)', 'class.meth5', '', None)])
|
||||
assert_node(doctree[1][1][9], ([desc_signature, ([desc_annotation, "property "],
|
||||
[desc_name, "meth5"])],
|
||||
[desc_content, ()]))
|
||||
assert 'Class.meth5' in domain.objects
|
||||
assert domain.objects['Class.meth5'] == ('index', 'class-meth5', 'method')
|
||||
assert domain.objects['Class.meth5'] == ('index', 'class.meth5', 'method')
|
||||
|
||||
# :abstractmethod:
|
||||
assert_node(doctree[1][1][10], addnodes.index,
|
||||
entries=[('single', 'meth6() (Class method)', 'class-meth6', '', None)])
|
||||
entries=[('single', 'meth6() (Class method)', 'class.meth6', '', None)])
|
||||
assert_node(doctree[1][1][11], ([desc_signature, ([desc_annotation, "abstract "],
|
||||
[desc_name, "meth6"],
|
||||
[desc_parameterlist, ()])],
|
||||
[desc_content, ()]))
|
||||
assert 'Class.meth6' in domain.objects
|
||||
assert domain.objects['Class.meth6'] == ('index', 'class-meth6', 'method')
|
||||
assert domain.objects['Class.meth6'] == ('index', 'class.meth6', 'method')
|
||||
|
||||
|
||||
def test_pyclassmethod(app):
|
||||
@@ -552,13 +552,13 @@ def test_pyclassmethod(app):
|
||||
[desc_content, (addnodes.index,
|
||||
desc)])]))
|
||||
assert_node(doctree[1][1][0], addnodes.index,
|
||||
entries=[('single', 'meth() (Class class method)', 'class-meth', '', None)])
|
||||
entries=[('single', 'meth() (Class class method)', 'class.meth', '', None)])
|
||||
assert_node(doctree[1][1][1], ([desc_signature, ([desc_annotation, "classmethod "],
|
||||
[desc_name, "meth"],
|
||||
[desc_parameterlist, ()])],
|
||||
[desc_content, ()]))
|
||||
assert 'Class.meth' in domain.objects
|
||||
assert domain.objects['Class.meth'] == ('index', 'class-meth', 'method')
|
||||
assert domain.objects['Class.meth'] == ('index', 'class.meth', 'method')
|
||||
|
||||
|
||||
def test_pystaticmethod(app):
|
||||
@@ -573,13 +573,13 @@ def test_pystaticmethod(app):
|
||||
[desc_content, (addnodes.index,
|
||||
desc)])]))
|
||||
assert_node(doctree[1][1][0], addnodes.index,
|
||||
entries=[('single', 'meth() (Class static method)', 'class-meth', '', None)])
|
||||
entries=[('single', 'meth() (Class static method)', 'class.meth', '', None)])
|
||||
assert_node(doctree[1][1][1], ([desc_signature, ([desc_annotation, "static "],
|
||||
[desc_name, "meth"],
|
||||
[desc_parameterlist, ()])],
|
||||
[desc_content, ()]))
|
||||
assert 'Class.meth' in domain.objects
|
||||
assert domain.objects['Class.meth'] == ('index', 'class-meth', 'method')
|
||||
assert domain.objects['Class.meth'] == ('index', 'class.meth', 'method')
|
||||
|
||||
|
||||
def test_pyattribute(app):
|
||||
@@ -596,13 +596,13 @@ def test_pyattribute(app):
|
||||
[desc_content, (addnodes.index,
|
||||
desc)])]))
|
||||
assert_node(doctree[1][1][0], addnodes.index,
|
||||
entries=[('single', 'attr (Class attribute)', 'class-attr', '', None)])
|
||||
entries=[('single', 'attr (Class attribute)', 'class.attr', '', None)])
|
||||
assert_node(doctree[1][1][1], ([desc_signature, ([desc_name, "attr"],
|
||||
[desc_annotation, ": str"],
|
||||
[desc_annotation, " = ''"])],
|
||||
[desc_content, ()]))
|
||||
assert 'Class.attr' in domain.objects
|
||||
assert domain.objects['Class.attr'] == ('index', 'class-attr', 'attribute')
|
||||
assert domain.objects['Class.attr'] == ('index', 'class.attr', 'attribute')
|
||||
|
||||
|
||||
def test_pydecorator_signature(app):
|
||||
@@ -648,10 +648,10 @@ def test_module_index(app):
|
||||
assert index.generate() == (
|
||||
[('d', [IndexEntry('docutils', 0, 'index', 'module-docutils', '', '', '')]),
|
||||
('s', [IndexEntry('sphinx', 1, 'index', 'module-sphinx', '', '', ''),
|
||||
IndexEntry('sphinx.builders', 2, 'index', 'module-sphinx-builders', '', '', ''), # NOQA
|
||||
IndexEntry('sphinx.builders.html', 2, 'index', 'module-sphinx-builders-html', '', '', ''), # NOQA
|
||||
IndexEntry('sphinx.config', 2, 'index', 'module-sphinx-config', '', '', ''),
|
||||
IndexEntry('sphinx_intl', 0, 'index', 'module-sphinx-intl', '', '', '')])],
|
||||
IndexEntry('sphinx.builders', 2, 'index', 'module-sphinx.builders', '', '', ''), # NOQA
|
||||
IndexEntry('sphinx.builders.html', 2, 'index', 'module-sphinx.builders.html', '', '', ''), # NOQA
|
||||
IndexEntry('sphinx.config', 2, 'index', 'module-sphinx.config', '', '', ''),
|
||||
IndexEntry('sphinx_intl', 0, 'index', 'module-sphinx_intl', '', '', '')])],
|
||||
False
|
||||
)
|
||||
|
||||
@@ -663,7 +663,7 @@ def test_module_index_submodule(app):
|
||||
index = PythonModuleIndex(app.env.get_domain('py'))
|
||||
assert index.generate() == (
|
||||
[('s', [IndexEntry('sphinx', 1, '', '', '', '', ''),
|
||||
IndexEntry('sphinx.config', 2, 'index', 'module-sphinx-config', '', '', '')])],
|
||||
IndexEntry('sphinx.config', 2, 'index', 'module-sphinx.config', '', '', '')])],
|
||||
False
|
||||
)
|
||||
|
||||
@@ -692,12 +692,12 @@ def test_modindex_common_prefix(app):
|
||||
restructuredtext.parse(app, text)
|
||||
index = PythonModuleIndex(app.env.get_domain('py'))
|
||||
assert index.generate() == (
|
||||
[('b', [IndexEntry('sphinx.builders', 1, 'index', 'module-sphinx-builders', '', '', ''), # NOQA
|
||||
IndexEntry('sphinx.builders.html', 2, 'index', 'module-sphinx-builders-html', '', '', '')]), # NOQA
|
||||
('c', [IndexEntry('sphinx.config', 0, 'index', 'module-sphinx-config', '', '', '')]),
|
||||
[('b', [IndexEntry('sphinx.builders', 1, 'index', 'module-sphinx.builders', '', '', ''), # NOQA
|
||||
IndexEntry('sphinx.builders.html', 2, 'index', 'module-sphinx.builders.html', '', '', '')]), # NOQA
|
||||
('c', [IndexEntry('sphinx.config', 0, 'index', 'module-sphinx.config', '', '', '')]),
|
||||
('d', [IndexEntry('docutils', 0, 'index', 'module-docutils', '', '', '')]),
|
||||
('s', [IndexEntry('sphinx', 0, 'index', 'module-sphinx', '', '', ''),
|
||||
IndexEntry('sphinx_intl', 0, 'index', 'module-sphinx-intl', '', '', '')])],
|
||||
IndexEntry('sphinx_intl', 0, 'index', 'module-sphinx_intl', '', '', '')])],
|
||||
True
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user