Sphinx extension for auto-generating API documentation for entire modules
—
Handles the mapping between API locations (where users import classes from) and source locations (where classes are actually defined), ensuring that cross-references work correctly in complex package hierarchies. This is essential for projects where the public API differs from the internal code organization.
Builds mappings between actual class locations and their API locations during the documentation build process.
def process_docstring(app: Sphinx, what: str, name: str, obj: object,
options: dict, lines: list[str]) -> None:
"""
Process docstrings to build class name mappings.
Connected to Sphinx's 'autodoc-process-docstring' event to track class
locations and build a mapping from actual module.Class names to their
API names.
Parameters:
- app: Sphinx application instance
- what: Type of object being documented ('class', 'function', etc.)
- name: The API name of the object
- obj: The actual Python object being documented
- options: Autodoc options
- lines: Docstring lines (not modified by this function)
Side Effects:
- Updates app.env.class_name_mapping dictionary with mappings
"""The function runs automatically during documentation generation. For a class defined at mypackage.internal.utils.Helper but imported as mypackage.Helper, it creates the mapping:
# Internal mapping created:
env.class_name_mapping['mypackage.internal.utils.Helper'] = 'mypackage.Helper'Resolves missing references by looking up class names in the mapping and creating proper cross-references.
def missing_reference_handler(app: Sphinx, env: BuildEnvironment, node: Node,
contnode: Element) -> Element:
"""
Handle missing references by resolving through name mappings.
Connected to Sphinx's 'missing-reference' event. When Sphinx cannot
resolve a reference, this handler checks if it can be resolved using
the class name mappings built during docstring processing.
Parameters:
- app: Sphinx application instance
- env: Build environment containing the class name mappings
- node: The pending_xref node that couldn't be resolved
- contnode: The node containing the text and formatting
Returns:
- Element: New resolved reference node, or None if still unresolvable
"""When documentation contains a reference like :class:mypackage.internal.utils.Helper`` but the user-facing API is mypackage.Helper, this function:
mypackage.internal.utils.Helpermypackage.HelperHandles merging of class name mappings when Sphinx processes multiple documentation sources.
def merge_mapping(app: Sphinx, env: BuildEnvironment, docnames: set[str],
env_other: BuildEnvironment) -> None:
"""
Merge class name mappings between build environments.
Connected to Sphinx's environment merge events to ensure class name
mappings are preserved when environments are combined during parallel
builds or incremental updates.
Parameters:
- app: Sphinx application instance
- env: Primary build environment
- docnames: Set of document names being processed
- env_other: Secondary environment to merge from
Side Effects:
- Updates env.class_name_mapping with mappings from env_other
"""The smart resolver integrates with Sphinx through event connections:
def setup(app: Sphinx) -> dict[str, bool]:
"""
Set up smart reference resolution with Sphinx.
Connects event handlers:
- 'autodoc-process-docstring': process_docstring
- 'missing-reference': missing_reference_handler
- Environment merge events: merge_mapping
Returns:
- dict: Parallel processing compatibility flags
"""When your package has a complex internal structure but presents a simple public API:
# Internal structure:
mypackage/
internal/
core/
algorithms.py # defines FastSolver class
__init__.py # imports: from .internal.core.algorithms import FastSolverUsers import: from mypackage import FastSolver
But autodoc references: mypackage.internal.core.algorithms.FastSolver
The smart resolver maps these correctly so cross-references work.
When you've reorganized your internal code but maintained backward compatibility in the public API:
# Old location: mypackage.utils.Helper
# New location: mypackage.internal.helpers.Helper
# Public API: from mypackage import Helper
# Smart resolver ensures references to any of these resolve to the same documentationInheritance diagrams often reference classes by their canonical (source) location rather than their API location. The smart resolver ensures these references point to the correct documentation pages.
# Environment attribute added by smart resolver
class BuildEnvironment:
class_name_mapping: dict[str, str] # Maps source_name -> api_nameThe mapping dictionary format:
module.path.ClassName (where class is actually defined)api.name.ClassName (where users import from)The smart resolver works through Sphinx's event system:
The smart resolver is designed to:
The smart resolver is essential for maintaining clean, working documentation in projects with complex API structures, ensuring that users can navigate documentation seamlessly regardless of internal code organization.
Install with Tessl CLI
npx tessl i tessl/pypi-sphinx-automodapi