Napoleon: custom section headers (#4387)

* Changes to allow for custom sections in google/numpy comments when parsing with napoleon

* fixed some formatting to pass flake8 tests
This commit is contained in:
Patrick Wingo
2018-02-15 13:16:23 -08:00
committed by Rob Ruana
parent 2602be13bc
commit e505cbb3be
4 changed files with 64 additions and 1 deletions

View File

@@ -174,6 +174,8 @@ Features added
* #4271: sphinx-build supports an option called ``-j auto`` to adjust numbers of
processes automatically.
* Napoleon: added option to specify custom section tags.
Features removed
----------------

View File

@@ -47,6 +47,7 @@ class Config(object):
napoleon_use_param = True
napoleon_use_rtype = True
napoleon_use_keyword = True
napoleon_custom_sections = None
.. _Google style:
https://google.github.io/styleguide/pyguide.html
@@ -241,6 +242,19 @@ class Config(object):
:returns: *bool* -- True if successful, False otherwise
napoleon_custom_sections : :obj:`list` (Defaults to None)
Add a list of custom sections to include, expanding the list of parsed sections.
The entries can either be strings or tuples, depending on the intention:
* To create a custom "generic" section, just pass a string.
* To create an alias for an existing section, pass a tuple containing the
alias name and the original, in that order.
If an entry is just a string, it is interpreted as a header for a generic
section. If the entry is a tuple/list/indexed container, the first entry
is the name of the section, the second is the section key to emulate.
"""
_config_values = {
'napoleon_google_docstring': (True, 'env'),
@@ -254,7 +268,8 @@ class Config(object):
'napoleon_use_ivar': (False, 'env'),
'napoleon_use_param': (True, 'env'),
'napoleon_use_rtype': (True, 'env'),
'napoleon_use_keyword': (True, 'env')
'napoleon_use_keyword': (True, 'env'),
'napoleon_custom_sections': (None, 'env')
}
def __init__(self, **settings):

View File

@@ -170,6 +170,9 @@ class GoogleDocstring(UnicodeMixin):
'yield': self._parse_yields_section,
'yields': self._parse_yields_section,
} # type: Dict[unicode, Callable]
self._load_custom_sections()
self._parse()
def __unicode__(self):
@@ -530,6 +533,23 @@ class GoogleDocstring(UnicodeMixin):
line and
not self._is_indented(line, self._section_indent)))
def _load_custom_sections(self):
# type: () -> None
if self._config.napoleon_custom_sections is not None:
for entry in self._config.napoleon_custom_sections:
if isinstance(entry, string_types):
# if entry is just a label, add to sections list,
# using generic section logic.
self._sections[entry.lower()] = self._parse_custom_generic_section
else:
# otherwise, assume entry is container;
# [0] is new section, [1] is the section to alias.
# in the case of key mismatch, just handle as generic section.
self._sections[entry[0].lower()] = \
self._sections.get(entry[1].lower(),
self._parse_custom_generic_section)
def _parse(self):
# type: () -> None
self._parsed_lines = self._consume_empty()
@@ -597,6 +617,10 @@ class GoogleDocstring(UnicodeMixin):
use_admonition = self._config.napoleon_use_admonition_for_examples
return self._parse_generic_section(section, use_admonition)
def _parse_custom_generic_section(self, section):
# for now, no admonition for simple custom sections
return self._parse_generic_section(section, False)
def _parse_usage_section(self, section):
# type: (unicode) -> List[unicode]
header = ['.. rubric:: Usage:', ''] # type: List[unicode]

View File

@@ -966,6 +966,28 @@ Parameters:
actual = str(GoogleDocstring(docstring, config))
self.assertEqual(expected, actual)
def test_custom_generic_sections(self):
docstrings=("""\
Really Important Details:
You should listen to me!
""",
""".. rubric:: Really Important Details
You should listen to me!
"""),\
("""\
Sooper Warning:
Stop hitting yourself!
""",""":Warns: **Stop hitting yourself!**
""")
testConfig=Config(napoleon_custom_sections=['Really Important Details',('Sooper Warning','warns')])
for docstring, expected in docstrings:
actual = str(GoogleDocstring(docstring, testConfig))
self.assertEqual(expected, actual)
class NumpyDocstringTest(BaseDocstringTest):
docstrings = [(