Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Sphinx Autosummary: Automated listing of member functions

How can I tell the autosummary extension not to only list a single class but also all the class' members?

If I use:

.. autosummary::

    MyClass

In the resulting html file, there will only be one short summary like:

MyClass(var1, var2,....) My Custom class to do fancy things...

What I actually want is something like:

MyClass(var1, var2,....) My Custom class to do fancy things...

MyClass.doA(var1, var2, ...) Does A very well

MyClass.doB(var1, var2, ...) Does B even better

How do I have to configure the autosummary directive in order to get this (apart from tediously naming all functions myself in the autosummary directive)? Thanks!

like image 924
SmCaterpillar Avatar asked Dec 13 '13 14:12

SmCaterpillar


3 Answers

You can extend the Autosummary directive like below and call it like this:

.. autoclass:: your.fully.qualified.path.to.the.Class
   :members:
   :undoc-members:

    .. rubric:: Methods

    .. autoautosummary:: your.fully.qualified.path.to.the.Class
        :methods:

    .. rubric:: Attributes

    .. autoautosummary:: your.fully.qualified.path.to.the.Class
        :attributes:

Code (in conf.py):

from sphinx.ext.autosummary import Autosummary
from sphinx.ext.autosummary import get_documenter
from docutils.parsers.rst import directives
from sphinx.util.inspect import safe_getattr
import re

class AutoAutoSummary(Autosummary):

    option_spec = {
        'methods': directives.unchanged,
        'attributes': directives.unchanged
    }

    required_arguments = 1

    @staticmethod
    def get_members(obj, typ, include_public=None):
        if not include_public:
            include_public = []
        items = []
        for name in dir(obj):
            try:
                documenter = get_documenter(safe_getattr(obj, name), obj)
            except AttributeError:
                continue
            if documenter.objtype == typ:
                items.append(name)
        public = [x for x in items if x in include_public or not x.startswith('_')]
        return public, items

    def run(self):
        clazz = str(self.arguments[0])
        try:
            (module_name, class_name) = clazz.rsplit('.', 1)
            m = __import__(module_name, globals(), locals(), [class_name])
            c = getattr(m, class_name)
            if 'methods' in self.options:
                _, methods = self.get_members(c, 'method', ['__init__'])

                self.content = ["~%s.%s" % (clazz, method) for method in methods if not method.startswith('_')]
            if 'attributes' in self.options:
                _, attribs = self.get_members(c, 'attribute')
                self.content = ["~%s.%s" % (clazz, attrib) for attrib in attribs if not attrib.startswith('_')]
        finally:
            return super(AutoAutoSummary, self).run()

def setup(app):
    app.add_directive('autoautosummary', AutoAutoSummary)
like image 187
clonker Avatar answered Nov 20 '22 12:11

clonker


You have to type out the class members as well

.. autosummary::

    MyClass
    MyClass.doA
    MyClass.doB

I like to split it up with titles or rubrics like

.. rubric:: Classes

.. autosummary::

    MyClass


.. rubric:: MyClass Members

.. autosummary::

    MyClass.doA
    MyClass.doB
like image 2
Rafe Avatar answered Nov 20 '22 13:11

Rafe


Maybe you should use autoclass provided by sphinx, You can approach that by replacing autosummary:

.. autoclass:: MyClass
   :members:
like image 1
iMom0 Avatar answered Nov 20 '22 13:11

iMom0