#564: Add :confval:autodoc_docstring_signature which retrieves the signature from the first line of the docstring, if it is found there.

This commit is contained in:
Georg Brandl 2011-01-03 22:51:33 +01:00
parent 594c1a90f4
commit f6cb763ff8
4 changed files with 84 additions and 4 deletions

View File

@ -12,6 +12,10 @@ Release 1.1 (in development)
* #460: Allow limiting the depth of section numbers for HTML.
* #564: Add :confval:`autodoc_docstring_signature` which retrieves
the signature from the first line of the docstring, if it is
found there.
* #176: Provide ``private-members`` option for autodoc directives.
* #520: Provide ``special-members`` option for autodoc directives.

View File

@ -285,6 +285,19 @@ There are also new config values that you can set:
.. versionadded:: 1.0
.. confval:: autodoc_docstring_signature
Functions imported from C modules cannot be introspected, and therefore the
signature for such functions cannot be automatically determined. However, it
is a well- convention
If this boolean value is set to ``True`` (which is the default), autodoc will
look at the first line of the docstring for functions and methods, and if it
looks like a signature, use the line as the signature and remove it from the
docstring content.
.. versionadded:: 1.1
Docstring preprocessing
-----------------------

View File

@ -827,7 +827,53 @@ class ClassLevelDocumenter(Documenter):
return modname, parents + [base]
class FunctionDocumenter(ModuleLevelDocumenter):
class DocstringSignatureMixin(object):
"""
Mixin for FunctionDocumenter and MethodDocumenter to provide the
feature of reading the signature from the docstring.
"""
def _find_signature(self, encoding=None):
docstrings = Documenter.get_doc(self, encoding)
if len(docstrings) != 1:
return
doclines = docstrings[0]
setattr(self, '__new_doclines', doclines)
if not doclines:
return
# match first line of docstring against signature RE
match = py_ext_sig_re.match(doclines[0])
if not match:
return
exmod, path, base, args, retann = match.groups()
# the base name must match ours
if not self.objpath or base != self.objpath[-1]:
return
# ok, now jump over remaining empty lines and set the remaining
# lines as the new doclines
i = 1
while i < len(doclines) and not doclines[i].strip():
i += 1
setattr(self, '__new_doclines', doclines[i:])
return args, retann
def get_doc(self, encoding=None):
lines = getattr(self, '__new_doclines', None)
if lines is not None:
return [lines]
return Documenter.get_doc(self, encoding)
def format_signature(self):
if self.args is None and self.env.config.autodoc_docstring_signature:
# only act if a signature is not explicitly given already, and if
# the feature is enabled
result = self._find_signature()
if result is not None:
self.args, self.retann = result
return Documenter.format_signature(self)
class FunctionDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter):
"""
Specialized Documenter subclass for functions.
"""
@ -841,8 +887,8 @@ class FunctionDocumenter(ModuleLevelDocumenter):
def format_args(self):
if inspect.isbuiltin(self.object) or \
inspect.ismethoddescriptor(self.object):
# can never get arguments of a C function or method
return None
# cannot introspect arguments of a C function or method
pass
try:
argspec = inspect.getargspec(self.object)
except TypeError:
@ -1008,7 +1054,7 @@ class DataDocumenter(ModuleLevelDocumenter):
pass
class MethodDocumenter(ClassLevelDocumenter):
class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter):
"""
Specialized Documenter subclass for methods (normal, static and class).
"""
@ -1235,6 +1281,7 @@ def setup(app):
app.add_config_value('autoclass_content', 'class', True)
app.add_config_value('autodoc_member_order', 'alphabetic', True)
app.add_config_value('autodoc_default_flags', [], True)
app.add_config_value('autodoc_docstring_signature', True, True)
app.add_event('autodoc-process-docstring')
app.add_event('autodoc-process-signature')
app.add_event('autodoc-skip-member')

View File

@ -492,6 +492,13 @@ def test_generate():
],
'class', 'Class', member_order='bysource', all_members=True)
# test autodoc_docstring_signature
assert_result_contains(
'.. py:method:: DocstringSig.meth(FOO, BAR=1) -> BAZ', 'method',
'test_autodoc.DocstringSig.meth')
assert_result_contains(
' rest of docstring', 'method', 'test_autodoc.DocstringSig.meth')
# --- generate fodder ------------
@ -582,3 +589,12 @@ class Outer(object):
# should be documented as an alias
factory = dict
class DocstringSig(object):
def meth(self):
"""
meth(FOO, BAR=1) -> BAZ
rest of docstring
"""