diff -r e2f4149501b2 CHANGES --- a/CHANGES Wed Jul 23 18:18:00 2008 +0300 +++ b/CHANGES Fri Jul 25 00:07:21 2008 +0300 @@ -19,6 +19,8 @@ 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.1 (Jul 5, 2008) =========================== diff -r e2f4149501b2 doc/ext/autodoc.rst --- a/doc/ext/autodoc.rst Wed Jul 23 18:18:00 2008 +0300 +++ b/doc/ext/autodoc.rst Fri Jul 25 00:07:21 2008 +0300 @@ -189,11 +189,11 @@ 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 @@ -211,9 +211,31 @@ 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 before autodoc has read and processed a docstring. 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 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 diff -r e2f4149501b2 sphinx/ext/autodoc.py --- a/sphinx/ext/autodoc.py Wed Jul 23 18:18:00 2008 +0300 +++ b/sphinx/ext/autodoc.py Fri Jul 25 00:07:21 2008 +0300 @@ -320,27 +320,48 @@ 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 '' + 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 + + if retann is None: + retann = "" + + results = self.env.app.emit('autodoc-process-signature', + what, name, obj, self.options, args, retann) + for r in results: + if r: + args, retann = r + + if args is not None: + return '%s%s' % (args, retann or '') + else: + raise RuntimeError(err) def generate(self, what, name, members, add_content, indent=u'', check_module=False): """ @@ -383,7 +404,7 @@ # 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 +617,4 @@ 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')