Search code examples
pythonpython-sphinxrestructuredtextread-the-docsautodoc

Sphinx / autodoc: how to cross-link to a function documented on another page


I am building a documentation of my Python package using Sphinx.

I have a API.rst file, in which I list my functions as follows: .. autofunction:: mymodule.foo.bar1

For the different functions that are autodocumented form this page, I can put for instance:

:func:`foo1` 

in the docstring of foo2() and it will create a link to the first function.

However, if I have a second file API2.rst, in which I autodoc some other functions, the same syntax doesn't seem to find the links across different pages. Even the See Also functions are not linked.

Is there a way to specify and to link different functions across pages? Thanks

Example

  • The repo's documentation can be found here
  • For instance, in the docstring of this function, under the parameter peaks, I am trying to link to another function called ecg_peaks() which is documented here

Solution

  • To sum up what other commenters found, when Sphinx resolve Python cross-references, it can find the cross-reference targets in several ways. Let's get an example.

    Say you have the following project structure

    my-project/
    ├── docs/            # Where your docs, and conf.py are
    └── my_project/      # where the Python code is, importable from Sphinx
        ├── __init__.py  # empty file
        ├── foobar.py    # defines the foo_func and bar_func functions
        └── baz.py       # defines the Baz class which as a baz_meth method
    
    • Absolute qualified name: Anywhere in your documentation you should be able to make a fully qualified reference, like so

      See the :func:`my_project.foobar.foo_func` function
      
    • Relative name: In a given module, you can use the Python object name directly. For instance, from within the from foobar.py file:

      See the :func:`foo_func` function.
      
    • Relaxed qualified name: When referencing a python object you can use the . character to extend the search space for your target. As an example, from foobar.py file:

      See the :func:`.foo_func` function.
      

      Also, from the class docstring of Baz, in baz.py:

      See the :meth:`.baz_meth` method.
      

      The risk with the relaxed method is that Sphinx will link to the first thing it finds, which may of may not be the target you expected.

    Finally, to help prevent these issues go public, use the nitpick option

    Here is what Sphinx documentation says on this topic

    The name enclosed in this markup can include a module name and/or a class name. For example, :py:func:filter could refer to a function named filter in the current module, or the built-in function of that name. In contrast, :py:func:foo.filter clearly refers to the filter function in the foo module.

    Normally, names in these roles are searched first without any further qualification, then with the current module name prepended, then with the current module and class name (if any) prepended. If you prefix the name with a dot, this order is reversed. For example, in the documentation of Python’s codecs module, :py:func:open always refers to the built-in function, while :py:func:.open refers to codecs.open().

    A similar heuristic is used to determine whether the name is an attribute of the currently documented class.

    Also, if the name is prefixed with a dot, and no exact match is found, the target is taken as a suffix and all object names with that suffix are searched. For example, :py:meth:.TarFile.close references the tarfile.TarFile.close() function, even if the current module is not tarfile. Since this can get ambiguous, if there is more than one possible match, you will get a warning from Sphinx.

    Note that you can combine the ~ and . prefixes: :py:meth:~.TarFile.close will reference the tarfile.TarFile.close() method, but the visible link caption will only be close().