mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
fix #2379 - Keyword args rendered with type links, as normal parameters (configurable under napoleon_use_keyword option)
This commit is contained in:
parent
15d89a2bfe
commit
d8cd3ec4be
@ -371,6 +371,22 @@ enabled in `conf.py`::
|
||||
* **arg2** (*int, optional*) --
|
||||
Description of `arg2`, defaults to 0
|
||||
|
||||
.. confval:: napoleon_use_keyword
|
||||
|
||||
True to use a ``:keyword:`` role for each function keyword argument.
|
||||
False to use a single ``:keyword arguments:`` role for all the
|
||||
keywords.
|
||||
*Defaults to True.*
|
||||
|
||||
This behaves similarly to :attr:`napoleon_use_param`. Note unlike docutils,
|
||||
``:keyword:`` and ``:param:`` will not be treated the same way - there will
|
||||
be a separate "Keyword Arguments" section, rendered in the same fashion as
|
||||
"Parameters" section (type links created if possible)
|
||||
|
||||
.. seealso::
|
||||
|
||||
:attr:`napoleon_use_param`
|
||||
|
||||
.. confval:: napoleon_use_rtype
|
||||
|
||||
True to use the ``:rtype:`` role for the return type. False to output
|
||||
|
@ -41,6 +41,7 @@ class Config(object):
|
||||
napoleon_use_ivar = False
|
||||
napoleon_use_param = True
|
||||
napoleon_use_rtype = True
|
||||
napoleon_use_keyword = True
|
||||
|
||||
.. _Google style:
|
||||
http://google.github.io/styleguide/pyguide.html
|
||||
@ -184,6 +185,20 @@ class Config(object):
|
||||
* **arg2** (*int, optional*) --
|
||||
Description of `arg2`, defaults to 0
|
||||
|
||||
napoleon_use_keyword : bool, defaults to True
|
||||
True to use a ``:keyword:`` role for each function keyword argument.
|
||||
False to use a single ``:keyword arguments:`` role for all the
|
||||
keywords.
|
||||
|
||||
This behaves similarly to :attr:`napoleon_use_param`. Note unlike docutils,
|
||||
``:keyword:`` and ``:param:`` will not be treated the same way - there will
|
||||
be a separate "Keyword Arguments" section, rendered in the same fashion as
|
||||
"Parameters" section (type links created if possible)
|
||||
|
||||
See Also
|
||||
--------
|
||||
:attr:`napoleon_use_param`
|
||||
|
||||
napoleon_use_rtype : bool, defaults to True
|
||||
True to use the ``:rtype:`` role for the return type. False to output
|
||||
the return type inline with the description.
|
||||
@ -216,6 +231,7 @@ class Config(object):
|
||||
'napoleon_use_ivar': (False, 'env'),
|
||||
'napoleon_use_param': (True, 'env'),
|
||||
'napoleon_use_rtype': (True, 'env'),
|
||||
'napoleon_use_keyword': (True, 'env')
|
||||
}
|
||||
|
||||
def __init__(self, **settings):
|
||||
@ -251,6 +267,8 @@ def setup(app):
|
||||
if not isinstance(app, Sphinx):
|
||||
return # probably called by tests
|
||||
|
||||
_patch_python_domain()
|
||||
|
||||
app.connect('autodoc-process-docstring', _process_docstring)
|
||||
app.connect('autodoc-skip-member', _skip_member)
|
||||
|
||||
@ -259,6 +277,23 @@ def setup(app):
|
||||
return {'version': sphinx.__display_version__, 'parallel_read_safe': True}
|
||||
|
||||
|
||||
def _patch_python_domain():
|
||||
import sphinx.domains.python
|
||||
from sphinx.domains.python import PyTypedField
|
||||
import sphinx.locale
|
||||
l_ = sphinx.locale.lazy_gettext
|
||||
for doc_field in sphinx.domains.python.PyObject.doc_field_types:
|
||||
if doc_field.name == 'parameter':
|
||||
doc_field.names = ('param', 'parameter', 'arg', 'argument')
|
||||
break
|
||||
sphinx.domains.python.PyObject.doc_field_types.append(
|
||||
PyTypedField('keyword', label=l_('Keyword Arguments'),
|
||||
names=('keyword', 'kwarg', 'kwparam'),
|
||||
typerolename='obj', typenames=('paramtype', 'kwtype'),
|
||||
can_collapse=True),
|
||||
)
|
||||
|
||||
|
||||
def _process_docstring(app, what, name, obj, options, lines):
|
||||
"""Process the docstring for a given python object.
|
||||
|
||||
|
@ -527,7 +527,15 @@ class GoogleDocstring(UnicodeMixin):
|
||||
return [header, '']
|
||||
|
||||
def _parse_keyword_arguments_section(self, section):
|
||||
return self._format_fields('Keyword Arguments', self._consume_fields())
|
||||
fields = self._consume_fields()
|
||||
if self._config.napoleon_use_keyword:
|
||||
return self._generate_docutils_params(
|
||||
fields,
|
||||
field_role="keyword",
|
||||
type_role="kwtype"
|
||||
)
|
||||
else:
|
||||
return self._format_fields('Keyword Arguments', fields)
|
||||
|
||||
def _parse_methods_section(self, section):
|
||||
lines = []
|
||||
@ -552,24 +560,26 @@ class GoogleDocstring(UnicodeMixin):
|
||||
def _parse_parameters_section(self, section):
|
||||
fields = self._consume_fields()
|
||||
if self._config.napoleon_use_param:
|
||||
lines = []
|
||||
for _name, _type, _desc in fields:
|
||||
_desc = self._strip_empty(_desc)
|
||||
if any(_desc):
|
||||
if self._is_list(_desc):
|
||||
_desc = [''] + _desc
|
||||
field = ':param %s: ' % _name
|
||||
lines.extend(self._format_block(field, _desc))
|
||||
else:
|
||||
lines.append(':param %s:' % _name)
|
||||
|
||||
if _type:
|
||||
lines.append(':type %s: %s' % (_name, _type))
|
||||
|
||||
return lines + ['']
|
||||
return self._generate_docutils_params(fields)
|
||||
else:
|
||||
return self._format_fields('Parameters', fields)
|
||||
|
||||
def _generate_docutils_params(self, fields, field_role='param', type_role='type'):
|
||||
lines = []
|
||||
for _name, _type, _desc in fields:
|
||||
_desc = self._strip_empty(_desc)
|
||||
if any(_desc):
|
||||
if self._is_list(_desc):
|
||||
_desc = [''] + _desc
|
||||
field = ':%s %s: ' % (field_role, _name)
|
||||
lines.extend(self._format_block(field, _desc))
|
||||
else:
|
||||
lines.append(':%s %s:' % (field_role, _name))
|
||||
|
||||
if _type:
|
||||
lines.append(':%s %s: %s' % (type_role, _name, _type))
|
||||
return lines + ['']
|
||||
|
||||
def _parse_raises_section(self, section):
|
||||
fields = self._consume_fields(parse_type=False, prefer_type=True)
|
||||
field_type = ':raises:'
|
||||
|
@ -249,7 +249,11 @@ class GoogleDocstringTest(BaseDocstringTest):
|
||||
)]
|
||||
|
||||
def test_docstrings(self):
|
||||
config = Config(napoleon_use_param=False, napoleon_use_rtype=False)
|
||||
config = Config(
|
||||
napoleon_use_param=False,
|
||||
napoleon_use_rtype=False,
|
||||
napoleon_use_keyword=False
|
||||
)
|
||||
for docstring, expected in self.docstrings:
|
||||
actual = str(GoogleDocstring(dedent(docstring), config))
|
||||
expected = dedent(expected)
|
||||
@ -1046,7 +1050,10 @@ class NumpyDocstringTest(BaseDocstringTest):
|
||||
)]
|
||||
|
||||
def test_docstrings(self):
|
||||
config = Config(napoleon_use_param=False, napoleon_use_rtype=False)
|
||||
config = Config(
|
||||
napoleon_use_param=False,
|
||||
napoleon_use_rtype=False,
|
||||
napoleon_use_keyword=False)
|
||||
for docstring, expected in self.docstrings:
|
||||
actual = str(NumpyDocstring(dedent(docstring), config))
|
||||
expected = dedent(expected)
|
||||
@ -1736,3 +1743,19 @@ definition_after_normal_text : int
|
||||
config = Config(napoleon_use_param=False)
|
||||
actual = str(NumpyDocstring(docstring, config))
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
def test_keywords_with_types(self):
|
||||
docstring = """\
|
||||
Do as you please
|
||||
|
||||
Keyword Args:
|
||||
gotham_is_yours (None): shall interfere.
|
||||
"""
|
||||
actual = str(GoogleDocstring(docstring))
|
||||
expected = """\
|
||||
Do as you please
|
||||
|
||||
:keyword gotham_is_yours: shall interfere.
|
||||
:kwtype gotham_is_yours: None
|
||||
"""
|
||||
self.assertEqual(expected, actual)
|
||||
|
Loading…
Reference in New Issue
Block a user