Search code examples
pythonpython-sphinxautodocnumpydoc

How to configure Sphinx autodoc to document classes in __init__.py?


I have Python codes with NumPy docstrings. Manage to use Sphinx for the API documentation, however, classes in the __init__.py file not documented successfully.

Example: xxx/__init__.py

from __future__ import annotations
import sys
import re
from typing import Iterator, ...
import pyparsing as p

__all__ = ['Xxx']

class XxxData:
    """It is a class XxxData."""
    def __init__(self):
        self.data = dict()

    def get_foo(self, foo) -> str:
        """Get foo bar.
        
        Parameters
        ----------
        foo : str
            It is just a string.

        Returns
        -------
        str
            It is just a string.
        """
        return f'{foo} bar'

class Xxx():
    """It is a class Xxx."""
    def __init__(self):
        super().__init__()
        self._something = 'something'

    def parse_bar(self, bar) -> XxxData:
        """Parse bar.

        Parameters
        ----------
        bar : str
            It is just a string.

        Returns
        -------
        XxxData
            It is a return object of XxxData.

        """
        print(f'Hello {bar}')
        data = XxxData()
        return data

Sample conf.py:

import os
import sys
sys.path.insert(0, os.path.abspath('../..'))

extensions = [
    'sphinx.ext.autodoc',       # Core library for html generation from docstrings
    'sphinx.ext.autosummary',   # Create neat summary tables
    'sphinx.ext.napoleon',      # Support for NumPy and Google style docstrings
]
autosummary_generate = True  # Turn on sphinx.ext.autosummary

autodoc_default_options = {
    'show-inheritance': False,
    'members': True,
    'member-order': 'bysource',
    'special-members': '__init__',
    'undoc-members': True,
    'exclude-members': '__weakref__'
}
autoclass_content = 'both'

I have also wrote a function to make sure that the sys.path append all required dependencies.

docs
|-Makefile
|-build
|-make.bat
|-source
  |-_static
  |-_templates
  |-conf.py
  |-index.rst
packages
|-pss
  |-src/dd
    |-ps
      |-xxx
        |-__init__.py

sphinx-apidoc command below auto created 3 rst files: source/api/ps.rst, source/api/ps.xxx.rst, source/api/modules.rst

sphinx-apidoc -o source/api/ ../packages/pss/src/dd/ps/ --implicit-namespaces -e -M -P

Sample source/api/ps.xxx.rst:

ps.xxx package
==============

.. automodule:: ps.xxx
   :members:
   :undoc-members:
   :show-inheritance:
   :private-members:

make html build succeeded but with warning below:

WARNING: autodoc: failed to import module 'xxx' from module 'ps'; the following exception was raised:
No module named 'ps.xxx'; 'ps' is not a package

HMTL page rendered with empty content. I'd like to see docstrings from the __init__.py (sample file above) documented, but did not happen.

Technically, would Sphinx work for classes/methods docstrings in __init__.py file? Should I concern about those warnings that happen during make html?

Appreciate any insights how to configure the Sphinx to close the gaps.


Solution

  • The sys.path below works for all the subpackages/modules except for the module with only __init__.py file. I used ../.. because the conf.py is 2 hierarchies below the top-level python source file folder.

    sys.path.insert(0, os.path.abspath('../..'))
    

    By explicitly append ../../packages/pss/src/dd to sys.path has resolved the issue for modules with only __init__.py file based on the defined example of the question.

    sys.path.insert(0, os.path.abspath('../../packages/pss/src/dd'))
    

    Apparently, it is a must to address all reported warnings to get the documentation rendered as expected.

    WARNING: autodoc: failed to import module 'xxx' from module 'ps'; the following exception was raised:
    No module named 'ps.xxx'; 'ps' is not a package