Search code examples
pythonpandaspython-sphinxautodoc

Documenting package __init__ imports with Sphinx


I have a Python package, felling which has a method:

from felling.src.email import send_email

Following from how Pandas handles imports such as pandas.DataFrame in felling.__init__.py I have:

# felling.__init__.py
from felling.src.email import send_email

Which allows someone to import felling.src.email.send_email by using:

from felling import send_email 

With this last import method being the main way I intend send_email to be imported. Nobody ever runs from pandas.core.api import DataFrame despite this being valid.

When documenting felling with Sphinx it documents send_email as felling.src.email.send_email not felling.email. I've read through Pandas docs and cannot figure how they get Sphinx to document pandas.core.api.DataFrame as pandas.DataFrame.

How can I do this?

Example .py

# felling.src.email

def send_email(to:str, subject:str):
    """
    Send an email

    Parameters
    ----------
    to : str
        Who should receive the email
    subject : str
        What should the emails subject be
    """
    print(to)
    print(subject)

Example .rst

felling methods
===============

A package for logging

felling.src.email
------------------------

.. automodule:: felling.src.email
   :members:
   :undoc-members:
   :show-inheritance:

Felling's tree

├── README.md
├── __init__.py
├── __main__.py
├── resources
│   └── logger.json
├── src
│   ├── __init__.py
│   ├── compare_logs.py
│   ├── configure_felling.py
│   └── email.py
└── version.py

Solution

  • Having a __init__.py file makes it possible that qualified names for classes and functions don't correspond directly to how modules are organized as files. A good example is given in this answer.

    The autodoc directives import your objects as you normally would in Python. The first argument of a directive should be the fully qualified name of the object it's importing, so any name the __init__.py changes to allow an import should also be usable as an argument to the directive.

    Directives - autodoc

    autodoc provides several directives that are versions of the usual py:module, py:class and so forth. On parsing time, they import the corresponding module and extract the docstring of the given objects, inserting them into the page source under a suitable py:module, py:class etc. directive.

    This means, in the case of the question, you could use:

    .. autofunction:: felling.send_email 
    

    or

    .. automodule:: felling