Merge pull request #3585 from eric-wieser/escape-autosummary

BUG: Fix autosummary of members with a trailing underscore
This commit is contained in:
Takeshi KOMIYA 2017-03-29 22:56:32 +09:00 committed by GitHub
commit 592b808005
8 changed files with 72 additions and 8 deletions

View File

@ -158,7 +158,7 @@ is not supported.)
may indicate that it's a better idea to write custom narrative documentation may indicate that it's a better idea to write custom narrative documentation
instead. instead.
Autosummary uses the following template files: Autosummary uses the following Jinja template files:
- :file:`autosummary/base.rst` -- fallback template - :file:`autosummary/base.rst` -- fallback template
- :file:`autosummary/module.rst` -- template for modules - :file:`autosummary/module.rst` -- template for modules
@ -194,7 +194,8 @@ The following variables available in the templates:
.. data:: underline .. data:: underline
A string containing ``len(full_name) * '='``. A string containing ``len(full_name) * '='``. Use the ``underline`` filter
instead.
.. data:: members .. data:: members
@ -227,7 +228,25 @@ The following variables available in the templates:
List containing names of "public" attributes in the class. Only available List containing names of "public" attributes in the class. Only available
for classes. for classes.
Additionally, the following filters are available
.. function:: escape(s)
Escape any special characters in the text to be used in formatting RST
contexts. For instance, this prevents asterisks making things bolt. This
replaces the builtin Jinja `escape filter`_ that does html-escaping.
.. function:: underline(s, line='=')
Add a title underline to a piece of text.
For instance, ``{{ fullname | escape | underline }}`` should be used to produce
the title of a page.
.. note:: .. note::
You can use the :rst:dir:`autosummary` directive in the stub pages. You can use the :rst:dir:`autosummary` directive in the stub pages.
Stub pages are generated also based on these directives. Stub pages are generated also based on these directives.
.. _`escape filter`: http://jinja.pocoo.org/docs/2.9/templates/#escape

View File

@ -34,6 +34,7 @@ from sphinx.ext.autosummary import import_by_name, get_documenter
from sphinx.jinja2glue import BuiltinTemplateLoader from sphinx.jinja2glue import BuiltinTemplateLoader
from sphinx.util.osutil import ensuredir from sphinx.util.osutil import ensuredir
from sphinx.util.inspect import safe_getattr from sphinx.util.inspect import safe_getattr
from sphinx.util.rst import escape as rst_escape
# Add documenters to AutoDirective registry # Add documenters to AutoDirective registry
from sphinx.ext.autodoc import add_documenter, \ from sphinx.ext.autodoc import add_documenter, \
@ -80,6 +81,12 @@ def _simple_warn(msg):
print('WARNING: ' + msg, file=sys.stderr) print('WARNING: ' + msg, file=sys.stderr)
def _underline(title, line='='):
if '\n' in title:
raise ValueError('Can only underline single lines')
return title + '\n' + line * len(title)
# -- Generating output --------------------------------------------------------- # -- Generating output ---------------------------------------------------------
def generate_autosummary_docs(sources, output_dir=None, suffix='.rst', def generate_autosummary_docs(sources, output_dir=None, suffix='.rst',
@ -110,6 +117,11 @@ def generate_autosummary_docs(sources, output_dir=None, suffix='.rst',
template_dirs.insert(0, template_dir) template_dirs.insert(0, template_dir)
template_loader = FileSystemLoader(template_dirs) template_loader = FileSystemLoader(template_dirs)
template_env = SandboxedEnvironment(loader=template_loader) template_env = SandboxedEnvironment(loader=template_loader)
template_env.filters['underline'] = _underline
# replace the builtin html filters
template_env.filters['escape'] = rst_escape
template_env.filters['e'] = rst_escape
# read # read
items = find_autosummary_in_files(sources) items = find_autosummary_in_files(sources)

View File

@ -1,5 +1,4 @@
{{ fullname }} {{ fullname | escape | underline}}
{{ underline }}
.. currentmodule:: {{ module }} .. currentmodule:: {{ module }}

View File

@ -1,5 +1,4 @@
{{ fullname }} {{ fullname | escape | underline}}
{{ underline }}
.. currentmodule:: {{ module }} .. currentmodule:: {{ module }}

View File

@ -1,5 +1,4 @@
{{ fullname }} {{ fullname | escape | underline}}
{{ underline }}
.. automodule:: {{ fullname }} .. automodule:: {{ fullname }}

View File

@ -4,4 +4,5 @@
:toctree: :toctree:
dummy_module dummy_module
underscore_module_
sphinx sphinx

View File

@ -0,0 +1,12 @@
"""
module with trailing underscores everywhere
"""
class class_(object):
""" Class """
def method_(_arg):
""" Method """
pass
def function_(_arg):
""" Function """
pass

View File

@ -13,6 +13,8 @@ from six import iteritems, StringIO
from sphinx.ext.autosummary import mangle_signature from sphinx.ext.autosummary import mangle_signature
from util import etree_parse
import pytest import pytest
html_warnfile = StringIO() html_warnfile = StringIO()
@ -103,3 +105,24 @@ def test_get_items_summary(app, status, warning):
'Test function take an argument ended with underscore.', 'Test function take an argument ended with underscore.',
'dummy_module.func') 'dummy_module.func')
assert autosummary_items['func'] == func_attrs assert autosummary_items['func'] == func_attrs
def str_content(elem):
if elem.text is not None:
return elem.text
else:
return ''.join(str_content(e) for e in elem)
@pytest.mark.sphinx('xml', **default_kw)
def test_escaping(app, status, warning):
from xml.etree import ElementTree
app.builder.build_all()
outdir = app.builder.outdir
docpage = outdir / 'underscore_module_.xml'
assert docpage.exists()
title = etree_parse(docpage).find('section/title')
assert str_content(title) == 'underscore_module_'