3

I maintain a Python package that is usually imported with a short standardized nickname, in the manner of import numpy as np or import pandas as pd. Let's say it's import foobar as fb.

I am using sphinx to document it, and in my conf.py I have 'sphinx.ext.autodoc' among my extensions, and default_role = 'py:obj'. This is a nice setup, because it means that whenever my docstrings or separate .rst files contain an uncluttered string like

See the `foobar.Thing` class documentation for more details. 

or even just

See the `Thing` class documentation for more details.

then the text within backticks automatically gets hyperlinked to the documentation for the foobar.Thing class. But what's missing is the ability to do this:

See the `fb.Thing` class documentation for more details.

The text fb.Thing does not get hyperlinked, because sphinx (or sphinx autodoc) does not know that fb is an alias for the foobar package. How do I tell it that this is the case?

NB: I know it's possible to do it with <> notation:

See the `fb.Thing <foobar.Thing>` class documentation for more details.

but the docstrings are designed to be read as plain text as well, so I'm hoping that this can be done without introducing this or other forms of :clutter:`...` into them, but rather somehow in the conf.py file or in the .. automodule:: statement.

jez
  • 14,867
  • 5
  • 37
  • 64

2 Answers2

0

This might be solvable with intersphinx. If a name isn't found in the local object inventory, it can search in external sources. You can add you own documentation as a intersphinx inventory.

Intersphinx configuration:

# ==============================================================================
# Sphinx.Ext.InterSphinx
# ==============================================================================
intersphinx_mapping = {
#  'python':       ('https://docs.python.org/3', None),
  'foobar': ('http://foobar.readthedocs.io/en/latest', None),
}

Usage:

At next, I want to document `fb.Thing <foobar:Thing>`, because it's a great implementation.

Further Resources:

Paebbels
  • 15,573
  • 13
  • 70
  • 139
  • Thanks for the suggestion. With the same number of additional characters, it's actually possible to do the same thing without intersphinx: `\`fb.Thing \`` (note the dot instead of the colon). But ideally I was trying to avoid this additional clutter in the docstring itself. – jez Dec 27 '19 at 18:08
  • Does Python know that `fb` is an alias to `foobar`? So I mean, is there any special attribute like `__module__` or similar, that would give a Python introspection code the possibility to see/find aliases? If not, I think it would be impossible to even extend Sphinx in a native way to create internal alias tables... – Paebbels Dec 27 '19 at 22:05
  • It would be fairly easy to "tell Python" this fact in various ways. You could, for example, duplicate the entry in `sys.modules` by saying `sys.modules['fb'] = sys.modules['foobar']`. And this duplication will be identifiable by any code that cares to inspect the `__name__` attribute of the modules found there, since `fb.__name__` is going to be equal to `'foobar'`. – jez Dec 27 '19 at 22:11
  • But I assume, you don't want to rewrite all import statements to that style, right? – Paebbels Dec 27 '19 at 22:51
  • No, but it could be done in `conf.py`. It only needs to be the case while Sphinx is running, I presume? – jez Dec 27 '19 at 22:58
  • @jez I think this would create doubled items in the module index and other doubled items and objects all over in the documentation ... – Paebbels Dec 28 '19 at 21:30
0

I don't know how to make sphinx aware of the module aliases, but this might be close to your desired notation:

somefile.py:

"""
Some documentation with references to an externally documented function

:func:`numpy.searchsorted` or :func:`partial.update_wrapper`
"""

conf.py:

# intersphinx settings
intersphinx_mapping = {'numpy': ('https://docs.scipy.org/doc/numpy', None),
                       'functools': ('https://docs.python.org/3.7/library/functools.html', None)}
BramAppel
  • 1,346
  • 1
  • 9
  • 21