Selectively disable inherited-members

Viewed 300

After much struggle with awful defaults in Sphinx, I finally found a way to display inherited methods in subclass documentation. Unfortunately, this option is global...

autodoc_default_options = {
    ...
    'inherited-members': True,
}

Is there any way to annotate any given class to prevent inherited methods and fields from showing in that documentation?

If there is no way to base it on inheritance, is there any way to simply list all the methods I don't want to be documented for a given class in its docstring?

I'm OK... well, I'd cry a little, but I'd live if I had to list the methods that need to be documented rather than blacklising the ones I don't want.

I know I can put :meta private: on a method definition to circumvent its inclusion in documentation (sort of, not really, but let's pretend it works), but in the case of inherited methods there's nowhere I can attach the docstring to.

Note that any "solution" that involves writing .. automodule:: section by hand is not a solution -- those must be generated.

1 Answers

Well, I figured how to solve half of the problem. Brace yourself for a lot of duct tape...

So, here's an example of how you can disable inherited fields in everything that extends directly or indirectly Exception class:

def is_error(obj):
    return issubclass(obj, Exception)


conditionally_ignored = {
    '__reduce__': is_error,
    '__init__': is_error,
    'with_traceback': is_error,
    'args': is_error,
}

def skip_member_handler(app, objtype, membername, member, skip, options):
    ignore_checker = conditionally_ignored.get(membername)
    if ignore_checker:
        frame = sys._getframe()
        while frame.f_code.co_name != 'filter_members':
            frame = frame.f_back

        suspect = frame.f_locals['self'].object
        return not ignore_checker(suspect)
    return skip


def setup(app):
    app.connect('autodoc-skip-member', skip_member_handler)

Put the above in your config.py. This implies that you are using autodoc to generate documentation.

In the end, I didn't go for controlling this behavior from the docstring of the class being documented. This is just too much work, and there are too many bugs in autodoc, Sphinx builders, the generated output and so on. Just not worth it.

But, the general idea would be to similarly add an event handler for when the source is read, extract information from docstrings, replace docstrings by patched docstrings w/o the necessary information, keep the extracted information somewhere until the skip handler is called, and then implement skipping. But, like I said, there are simply too many things broken along this line.

Another approach would be to emit XML, patch it with XSLT and feed it back to Docutils, but at the time of writing XML generator is broken (it adds namespaced attributes to XML, while it doesn't declare namespaces...) Old classic.

Yet another approach would've been handling an event, when, say the document is generated and references are resolved. Unfortunately, at that point, you will be missing information such as types of things you are working with, the original docstrings etc. You'll be essentially patching HTML, but with very convoluted structure.

Related