'Sphinx: how to show attributes as in scipy

Let's say we have the following module testmodule.py with a TestClass definition:

"""This is a test module"""

class TestClass:
    """
    This is a simple description.

    Attributes
    ----------
    egg : int
        An egg. Should be from a chiken.
    animal : str
        The animal that laid the egg.

    """

    def __init__(self, egg, animal):
        self.animal = animal
        if self.is_chicken(animal):
            self.egg = egg
        else:
            self.egg = 0

    def is_chicken(self, animal):
        """Checks if the animal is a chicken.

        Returns True if it is, False otherwise

        Parameters
        ----------
        animal : str
            An animal that lays eggs

        Returns
        -------
        bool
            True if `animal` is chicken. False otherwise.
        """
        if animal == 'chicken':
            return True
        else:
            return False

Using Sphinx 3.5.4 with autodoc and napoleon extensions, and pydata_sphinx_theme as the theme in conf.py, I get the doc for the class shown below.

I used .. automodule:: testmodule in a test.rst file, that index.rst references, with :member: and :show-inheritance:.

enter image description here

But I would actually like something more like Scipy has for the attributes.

enter image description here

The closest I can get is by setting napoleon_use_ivar = True in conf.py, which outputs something close, except that we get "Variables" instead of "Attributes" and the definition is inlined with the attribute name and type.

enter image description here



Solution 1:[1]

To get the desired output, instead of using sphinx.ext.napoleon, use numpydoc. It has to be loaded after sphinx.ext.autodoc, according to the Matplotlib conf.py file.

Additionally, since no summary table of the methods is desired, simply set numpydoc_show_class_members to False.

I was having another issue where multiple descriptions for parameters and attributes appeared. Turns out, it's because I was documenting them by hand in the class docstring but also using type-hints (for static type checking with pyright) and autodoc_typehints was set to document. This wasn't an issue when using sphinx napoleon, because it is implemented according to this sphinx napoleon RTD. But there is an open issue in numpydoc since 2019 to allow for type annotations. So the workaround is to set autodoc_typehints either to none or to signature.

In summary, in the conf.py file set:

extensions = [
    'sphinx.ext.autodoc',
    'numpydoc',  # needs to be loaded *after* autodoc
]
# NOTE: numpydoc automatically loads autosummary.
numpydoc_show_class_members = False
autodoc_typehints = "none"

And we get:

enter image description here

Now I just have to figure out how to keep the new lines between the attribute type and its description in pdf documents...

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Breno