24

CPython doesn't use autodoc for its documentation - we use hand-written prose.

For PEP 3144 (the ipaddress module), I'd like to use sphinx-apidoc to generate the initial reference documentation. That means I want to run a two-pass operation:

  1. Use sphinx-apidoc to emit a Sphinx project for the module that depends on autodoc

  2. Run a sphinx builder that creates new reStructuredText source files, with all the autodoc directives replaced by inline reStructuredText content and markup that produces the same output

The first step is straightforward, but I have no idea how to do the second step and can't even think of good ways to search for any existing projects along these lines.

bad_coder
  • 11,289
  • 20
  • 44
  • 72
ncoghlan
  • 40,168
  • 10
  • 71
  • 80
  • whats wrong about using rst files generated by autodoc (so only autodirectives no full py-domain definitions) and extend them? – bmu May 02 '12 at 21:45
  • ipaddress already has extensive docstrings, so I don't want to have to copy and paste them and reformat them by hand for the rest docs. – ncoghlan May 04 '12 at 07:52
  • So why do you have to copy them? You can write your additional documentation 'between' the auto directives and let sphinx translate it, no need to copy. Sorry perhaps I don't understand you (or your question). – bmu May 04 '12 at 12:37
  • @ncoghlan: Any feedback on the two answers provided? I will award the bounty tomorrow. – Steven Rumbalski May 08 '12 at 14:31
  • @bmu The CPython docs build process doesn't have autodoc enabled (by deliberate choice) – ncoghlan May 09 '12 at 04:31
  • @ncoghlan As I don't know the advantages of not to use `sphinx.autodoc` I ask this in http://stackoverflow.com/q/10523653/1301710 – bmu May 09 '12 at 20:32

2 Answers2

9

I had same problem and for one time generating of docs I've used quite ugly solution to patch Sphinx, see Make Sphinx generate RST class documentation from pydoc.

Community
  • 1
  • 1
Michal Čihař
  • 9,799
  • 6
  • 49
  • 87
  • +1 as I think this is the only way to get the rst-source fully formatted by autodoc. There should be an event in autodoc to get it. (also see my answer). – bmu May 04 '12 at 12:53
3

Not a full answer, more or less a starting point:

autodoc translates auto directives to python directives. So one can use autodoc events to get the translated python directives.

For example if you have the following mymodule.py:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
This is my module.
"""

def my_test_func(a, b=1):
    """This is my test function"""
    return a + b 

class MyClass(object):
    """This is my class"""

    def __init__(x, y='test'):
        """The init of my class"""
        self.x = float(x)
        self.y = y 

    def my_method(self, z): 
        """This is my method.

        :param z: a number
        :type z: float, int
        :returns: the sum of self.x and z
        :rtype: float
        """
        return self.x + z 

sphinx-apidoc will create

mymodule Module
===============

.. automodule:: mymodule
    :members:
    :undoc-members:
    :show-inheritance:

The following extension (or addition to conf.py):

NAMES = []
DIRECTIVES = {}

def get_rst(app, what, name, obj, options, signature,
            return_annotation):
    doc_indent = '    '
    directive_indent = ''
    if what in ['method', 'attribute']:
        doc_indent += '    '
        directive_indent += '    '
    directive = '%s.. py:%s:: %s' % (directive_indent, what, name)
    if signature:  # modules, attributes, ... don't have a signature
        directive += signature
    NAMES.append(name)
    rst = directive + '\n\n' + doc_indent + obj.__doc__ + '\n'
    DIRECTIVES[name] = rst 

def write_new_docs(app, exception):
    txt = ['My module documentation']
    txt.append('-----------------------\n')
    for name in NAMES:
        txt.append(DIRECTIVES[name])
    print '\n'.join(txt)
    with open('../doc_new/generated.rst', 'w') as outfile:
        outfile.write('\n'.join(txt))

def setup(app):
    app.connect('autodoc-process-signature', get_rst)
    app.connect('build-finished', write_new_docs)

will give you:

My module documentation
-----------------------

.. py:module:: mymodule


This is my module.


.. py:class:: mymodule.MyClass(x, y='test')

    This is my class

    .. py:method:: mymodule.MyClass.my_method(z)

        This is my method.

        :param z: a number
        :type z: float, int
        :returns: the sum of self.x and z
        :rtype: float


.. py:function:: mymodule.my_test_func(a, b=1)

    This is my test function

However as autodoc emits no event, when the translation is completed, So further processing done by autodoc has to be adapted to the docstrings here.

bmu
  • 35,119
  • 13
  • 91
  • 108