Skip to content.

plope

Personal tools
You are here: Home » Members » chrism's Home » Sphinx "autointerface" Autodoc Patch
 
 

Sphinx "autointerface" Autodoc Patch

Sphinx' "autodoc" extension allows you to generate docs from existing code. It doesn't like Zope interfaces, however. Included is a very raw patch that allows you to use autodoc to point at a Zope interface and generate documentation output for it.

This should really be its own Sphinx extension, but it was convenient to hack the autodoc module. It only handles methods, not attributes so far.

To show interface docs like this, put this in your markup like so (analogous to the autoclass directive):

  ..autointerface: my.interface.Class
    :members:

After applying this patch:

 Index: ext/autodoc.py
 ===================================================================
 --- ext/autodoc.py     (revision 62203)
 +++ ext/autodoc.py     (working copy)
 @@ -78,7 +78,7 @@
      if what == 'module':
          mod = obj = name
          objpath = []
 -    elif what in ('class', 'exception', 'function'):
 +    elif what in ('class', 'exception', 'function', 'interface'):
          mod, obj = rpartition(name, '.')
          if not mod and hasattr(env, 'autodoc_current_module'):
              mod = env.autodoc_current_module
 @@ -107,11 +107,18 @@
              if modfile.lower().endswith('.pyc') or modfile.lower().endswith('.pyo'):
                  modfile = modfile[:-1]
              filename_set.add(modfile)
 -        for part in objpath:
 -            todoc = getattr(todoc, part)
 -        if hasattr(todoc, '__module__'):
 -            if todoc.__module__ != mod:
 -                return [], result
 +        if what == 'interface_method':
 +            ifirst, ilast = objpath[0:-1], objpath[-1]
 +            for part in ifirst:
 +                todoc = getattr(todoc, part)
 +            todoc = todoc[ilast]
 +        else:
 +            for part in objpath:
 +                todoc = getattr(todoc, part)
 +        if what != 'interface_method':
 +            if hasattr(todoc, '__module__'):
 +                if todoc.__module__ != mod:
 +                    return [], result
          docstring = todoc.__doc__
      except (ImportError, AttributeError):
          warning = document.reporter.warning(
 @@ -130,6 +137,8 @@
                      args = '(' + args[7:]
                  elif args == '(self)':
                      args = '()'
 +        elif what == 'interface_method':
 +            args = todoc.getSignatureString()
          else:
              args = ''
      except:
 @@ -164,7 +173,8 @@
          for line, src in zip(add_content.data, add_content.items):
              result.append(indent + line, src[0], src[1])

 -    if not members or what in ('function', 'method', 'attribute'):
 +    if not members or what in ('function', 'method', 'attribute',
 +                               'interface_method'):
          return [], result

      env.autodoc_current_module = mod
 @@ -175,11 +185,17 @@
      # add members, if possible
      _all = members == ['__all__']
      if _all:
 -        all_members = sorted(inspect.getmembers(todoc))
 +        if what == 'interface':
 +            all_members = [ (mname, todoc[mname]) for mname in list(todoc) ]
 +        else:
 +            all_members = sorted(inspect.getmembers(todoc))
      else:
 -        all_members = [(mname, getattr(todoc, mname)) for mname in members]
 +        if what == 'interface':
 +            all_members = [ (name, todoc[mname]) for mname in  members ]
 +        else:
 +            all_members = [(mname, getattr(todoc, mname)) for mname in members]
      for (membername, member) in all_members:
 -        if _all and membername.startswith('_'):
 +        if _all and (not what == 'interface') and membername.startswith('_'):
              continue
          doc = getattr(member, '__doc__', None)
          if not undoc and not doc:
 @@ -196,6 +212,12 @@
              else:
                  # XXX: todo -- attribute docs
                  continue
 +        if what == 'interface':
 +            if hasattr(member, 'required'):
 +                memberwhat = 'interface_method'
 +            else:
 +                memberwhat = 'interface_attribute'
 +
          else:
              if callable(member):
                  memberwhat = 'method'
 @@ -225,9 +247,9 @@
      undoc = 'undoc-members' in options

      filename_set = set()
 +    
      warnings, result = generate_rst(what, name, members, undoc, content,
                                      state.document, lineno, filename_set=filename_set)
 -
      # record all filenames as dependencies -- this will at least partially make
      # automatic invalidation possible
      for fn in filename_set:
 @@ -260,16 +282,23 @@
          return ['__all__']
      return [x.strip() for x in arg.split(',')]

 -
  def setup(app):
      options = {'members': members_directive, 'undoc-members': directives.flag}
      app.add_directive('automodule', auto_directive_withmembers,
                        1, (1, 0, 1), **options)
      app.add_directive('autoclass', auto_directive_withmembers,
                        1, (1, 0, 1), **options)
 +    app.add_directive('autointerface', auto_directive_withmembers,
 +                      1, (1, 0, 1), **options)
      app.add_directive('autoexception', auto_directive_withmembers,
                        1, (1, 0, 1), **options)
      app.add_directive('autofunction', auto_directive, 1, (1, 0, 1))
      app.add_directive('automethod', auto_directive, 1, (1, 0, 1))
      app.add_directive('autoattribute', auto_directive, 1, (1, 0, 1))
      app.add_config_value('automodule_skip_lines', 0, True)
 +    from sphinx.directives import desc_directive
 +    from sphinx.directives import additional_xref_types
 +    additional_xref_types['interface'] = ('interface', 'interface; %s', None)
 +    additional_xref_types['interface_method'] = ('interface_method', 'interface method; %s', None)
 +    app.add_directive('interface', desc_directive, 1, (1, 0, 1))
 +    app.add_directive('interface_method', desc_directive, 1, (1, 0, 1))

Created by chrism
Last modified 2008-04-07 09:29 AM