Skip to content

Help people using Intersphinx against objects imported from a package __init__.py #5603

@cblegare

Description

@cblegare

Subject: Intersphinx references to objects imported at package level can't be mapped.

Problem

References to objects that are imported in their package's __init__.py can't be referenced using the default objects inventory generation.

The issue here is inconsistent default behavior of sphinx-apidoc and intersphinx.

Procedure to reproduce the problem

Here is an example involving marshmallow

import marshmallow

class MySchema(marshmallow.Schema):
    pass

Build the apidoc then HTML docs using intersphinx:

sphinx.errors.SphinxWarning: /home/me/example.py:docstring of example.MySchema:1:py:class reference target not found: marshmallow.schema.Schema

No matter how I import the class, marshmallow.Schema is in objects.inv but intersphinx will always look for marshmallow.schema.Schema.

Work around

One could add aliased entries in the inventory in conf.py:

intersphinx_aliases = {
    # Alias for a class that was imported at its package level
    ('py:class', 'marshmallow.schema.Schema'):
        ('py:class', 'marshmallow.Schema'),
    # Alias for unavailable apidoc having a equivalent entry somewhere else 
    ('py:class', 'defusedxml.cElementTree'):
        ('py:class', 'xml.etree.ElementTree.ElementTree'),
}


def add_intersphinx_aliases_to_inv(app):
    from sphinx.ext.intersphinx import InventoryAdapter
    inventories = InventoryAdapter(app.builder.env)

    for alias, target in app.config.intersphinx_aliases.items():
        alias_domain, alias_name = alias
        target_domain, target_name = target
        try:
            found = inventories.main_inventory[target_domain][target_name]
            try:
                inventories.main_inventory[alias_domain][alias_name] = found
            except KeyError:
                continue
        except KeyError:
            continue


def setup(app):
    app.add_config_value('intersphinx_aliases', {}, 'env')
    app.connect('builder-inited', add_intersphinx_aliases_to_inv)

This workaround is IMO cleaner than using https://github.com/bskinn/sphobjinv to play with objects.inv files.

Varia

I don't know how things could be improved to help users get coherent results by default, but I do hope that this issue expose a behavior issue and this workaround help someone

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions