#3422: allow changing the signature of functions via a new hook.

This commit is contained in:
Georg Brandl 2008-07-29 18:30:23 +00:00
parent 28e115cec1
commit b4f91a5ce5
4 changed files with 69 additions and 20 deletions

View File

@ -24,6 +24,9 @@ New features added
to disable the anchor-link creation after headlines and definition
links. EXPERIMENTAL
* sphinx.doc.autodoc has a new event ``autodoc-process-signature`` that
allows tuning function signature introspection.
Release 0.4.2 (Jul 29, 2008)
============================

View File

@ -189,12 +189,12 @@ There are also new config values that you can set:
Docstring preprocessing
-----------------------
.. versionadded:: 0.4
autodoc provides the following additional event:
autodoc provides the following additional events:
.. event:: autodoc-process-docstring (app, what, name, obj, options, lines)
.. versionadded:: 0.4
Emitted when autodoc has read and processed a docstring. *lines* is a list
of strings -- the lines of the processed docstring -- that the event handler
can modify **in place** to change what Sphinx puts into the output.
@ -211,9 +211,32 @@ autodoc provides the following additional event:
auto directive
:param lines: the lines of the docstring, see above
.. event:: autodoc-process-signature (app, what, name, obj, options, signature, return_annotation)
.. versionadded:: 0.5
Emitted when autodoc has formatted a signature for an object. The event
handler can return a new tuple ``(signature, return_annotation)`` to change
what Sphinx puts into the output.
:param app: the Sphinx application object
:param what: the type of the object which the docstring belongs to (one of
``"module"``, ``"class"``, ``"exception"``, ``"function"``, ``"method"``,
``"attribute"``)
:param name: the fully qualified name of the object
:param obj: the object itself
:param options: the options given to the directive: an object with attributes
``inherited_members``, ``undoc_members``, ``show_inheritance`` and
``noindex`` that are true if the flag option of same name was given to the
auto directive
:param signature: function signature, as a string of the form
``"(parameter_1, parameter_2)"``, or ``None`` if introspection didn't succeed
and signature wasn't specified in the directive.
:param return_annotation: function return annotation as a string of the form
``" -> annotation"``, or ``None`` if there is no return annotation
The :mod:`sphinx.ext.autodoc` module provides factory functions for commonly
needed docstring processing:
needed docstring processing in event :event:`autodoc-process-docstring`:
.. autofunction:: cut_lines
.. autofunction:: between

View File

@ -3,7 +3,7 @@ import ez_setup
ez_setup.use_setuptools()
import sys
from setuptools import setup, Feature
from setuptools import setup
import sphinx

View File

@ -320,27 +320,49 @@ class RstGenerator(object):
mod = self.env.currmodule
return fullname, mod, [cls, base], args, retann
def format_signature(self, what, obj, args, retann):
def format_signature(self, what, name, obj, args, retann):
"""
Return the signature of the object, formatted for display.
"""
if what not in ('class', 'method', 'function'):
return ''
err = None
if args is not None:
# signature given explicitly
return '(%s)%s' % (args, retann or '')
if what == 'class':
# for classes, the relevant signature is the __init__ method's
obj = getattr(obj, '__init__', None)
# classes without __init__ method?
if obj is None or obj is object.__init__ or not \
(inspect.ismethod(obj) or inspect.isfunction(obj)):
return ''
argspec = inspect.getargspec(obj)
if what in ('class', 'method') and argspec[0] and \
argspec[0][0] in ('cls', 'self'):
del argspec[0][0]
return inspect.formatargspec(*argspec)
args = "(%s)" % args
else:
# try to introspect the signature
try:
if what == 'class':
# for classes, the relevant signature is the __init__ method's
obj = getattr(obj, '__init__', None)
# classes without __init__ method?
if obj is None or obj is object.__init__ or not \
(inspect.ismethod(obj) or inspect.isfunction(obj)):
return ''
argspec = inspect.getargspec(obj)
if what in ('class', 'method') and argspec[0] and \
argspec[0][0] in ('cls', 'self'):
del argspec[0][0]
args = inspect.formatargspec(*argspec)
except Exception, e:
args = None
err = e
results = self.env.app.emit('autodoc-process-signature',
what, name, obj, self.options, args, retann)
for result in results:
if result:
args, retann = result
if args is not None:
return '%s%s' % (args, retann or '')
elif err:
# re-raise the error for perusal of the handler in generate()
raise RuntimeError(err)
else:
return ''
def generate(self, what, name, members, add_content, indent=u'', check_module=False):
"""
@ -383,7 +405,7 @@ class RstGenerator(object):
# format the object's signature, if any
try:
sig = self.format_signature(what, todoc, args, retann)
sig = self.format_signature(what, name, todoc, args, retann)
except Exception, err:
self.warn('error while formatting signature for %s: %s' %
(fullname, err))
@ -596,3 +618,4 @@ def setup(app):
app.add_config_value('automodule_skip_lines', 0, True)
app.add_config_value('autoclass_content', 'class', True)
app.add_event('autodoc-process-docstring')
app.add_event('autodoc-process-signature')