Skip to content Skip to sidebar Skip to footer

Can Sphinx Ignore Certain Tags In Python Docstrings?

I'm documenting my project with sphinx and using the sphinxcontrib.napoleon extension which lets me use google style docstrings. Here is a function from my project def nn_normaliz

Solution 1:

Ok, I think I've got a solution for you:

sphinx.ext.autodoc offers a listener sphinx.ext.autodoc.between that can be used to determine what parts of the docstrings autodoc collects should be kept or discarded:

sphinx.ext.autodoc.between(marker, what=None, keepempty=False, exclude=False)

Return a listener that either keeps, or if exclude is True excludes, lines between lines that match the marker regular expression. If no line matches, the resulting docstring would be empty, so no change will be made unless keepempty is true.

If what is a sequence of strings, only docstrings of a type in what will be processed.

sphinxcontrib.napoleon works on the docstrings that autodoc collects, so this should work for napoleon as well.

Usage example

Change your docstring like this:

"""
Args:
    ...

Returns:
    ...

IGNORE:
    #from ibeis.model.hots import neighbor_index as hsnbrx
    #nnindexer = hsnbrx.new_ibeis_nnindexer(ibs, daid_list)
IGNORE
"""

So make sure to surround the part you want to exclude with two lines that contain a unique marker (in this example the uppercase word IGNORE).

Add the following to your Sphinx project's conf.py (I'd probably append it all at the bottom as one block, but that's your call):

from sphinx.ext.autodoc import between

defsetup(app):
    # Register a sphinx.ext.autodoc.between listener to ignore everything# between lines that contain the word IGNORE
    app.connect('autodoc-process-docstring', between('^.*IGNORE.*$', exclude=True))
    return app

(If your conf.py already contains a setup() function, just extend it accordingly).

This will create and register a listener that gets called everytime autodoc processes a docstring. The listener then gets the chance to filter the docstring. In this example, the listener will discard everything between lines that match the regular expression ^.*IGNORE.*$ - so it's up to you to choose this expression so that it's specific enough for your project, but doesn't require a marker that adds too much noise.

(Note: If all you change is your conf.py, Sphinx won't pick up that change because the doctree didn't change. So make sure you run make clean (or rm -rf _build/*) before building your docs again).

Solution 2:

I stumbled upon this question I wrote 7 years ago today.

At the time I thought Lukas Graf's answer would be fine, but being forced to have and open and close Ignore tag was too much overhead (espeically in Python), so I stopped doing it and I forgot about it. Fast forward, my API docs are littered with ignores, and I really want to get rid of them. I looked at the answer with older and wiser eyes, and I have an actual solution that isn't hacky. This actually solves the problem.

def setup(app):
    # https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.htmlfrom sphinx.application import Sphinx
    from typing import Any, List

    what = None
    # Custom process to transform docstring lines# Remove "Ignore" blocks
    def process(app: Sphinx, what_: str, name: str, obj: Any, options: Any, lines: List[str]
                ) -> None:
        if what and what_ not in what:
            return
        orig_lines = lines[:]

        ignoring = False
        new_lines = []
        for i, line in enumerate(orig_lines):
            if line.startswith('Ignore'):
                # We will start ignoring everything indented after this
                ignoring = Trueelse:
                # if the line startswith anything but a space stop# ignoring the indented region.if ignoring and line and not line.startswith(' '):
                    ignoring = Falseif not ignoring:
                new_lines.append(line)

        lines[:] = new_lines
        # make sure there is a blank line at the endif lines and lines[-1]:
            lines.append('')

    app.connect('autodoc-process-docstring', process)
    return app

The idea is very similar, except I looked at the source code of what "between" does, and it is possible to just write your own custom function that processes your docstring in whatever way you want (although it is postprocessed by neopoleon, but that doesn't matter in this case).

Given the lines of each processsed docstring I can check to see if it starts with Ignore, then ignore everything until the indendation scope ends. No regex "between" tags needed.

Post a Comment for "Can Sphinx Ignore Certain Tags In Python Docstrings?"