You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Intersphinx does not create references to external project when using import as alias #10151
I'm creating a code docu using the docstring included in the code. In the conf.py file the intersphinx extension is included with mapping dicts to numpy, scipy, matplotlib, ...
E. g. When I import numpy as np or from typing import List, the external references do not exists in the build html docu as expected. It only works for standard python types.
I could not find anything in the Sphinx docu about this. Is this a bug or how must Sphinx be configured here?
How to Reproduce
$ git clone https://github.com/.../some_project
$ cd some_project
$ pip install -r requirements.txt
$ cd docs
$ make html SPHINXOPTS="-D language=de"
$ # open _build/html/index and see bla bla
Expected behavior
When I use absolute import like import numpy, import typing, the external docu is references in the html docu.
I would expected that the external docu references are created also for the import aliases.
I had this problem a while ago, which was why I subscribed to this thread. I found using type hints solves this problem. I don't know if it's worth it to you to switch, but... Also with proper type hints you can use the autodoc-process-signature callback to further modify the presentation of the type hint signatures.
Types in docstring
None of these are "clickable" except float.
deffunc_2(x, y):
""" This is the docstring of func_2. Parameters ---------- x: np.ndarray The first argument. y: np.ndarray The second argument. Returns ------- List[float] The return value. """pass
Types as type hints
All of these are "clickable".
deffunc(x: np.ndarray, y: np.ndarray) ->List[float]:
""" This is the docstring of func. Parameters ---------- x The first argument. y The second argument. Returns ------- The return value. """pass
Conf.py
intersphinx_mapping= {
"python": ("https://docs.python.org/3", None),
"numpy": ("https://numpy.org/doc/stable/", None),
}
autodoc_typehints="both"# autodoc_typehints_format = "short" # This is handy too
You can optionally add the autodoc-process-signature callback if you'd like.
OK I think I see the difference now. When you use a docstring generator as you have it in some python IDEs, it typically generates the docstring with the type included as it is defined in the docstring conventions: Numpy Docstring Format.
deffunc(self, val: np.ndarray) ->List[float]:
"""docstring of func Args: val (np.ndarray): Input argument Returns: List[float]: return value """return
--> When you delete all typehints in the docstring, it works.
deffunc(self, val: np.ndarray) ->List[float]:
"""docstring of func Args: val: Input argument Returns: return value """return
Does that mean the link to the numpy doc is overwritten?
That's a bummer. It appears that the docstring types supersede the function's actual annotations. I would've hoped for the opposite.
There's clearly an issue (as you reported) with how Napoleon processes types from the docstring. The workaround I've used is to simply remove types from the docstring and use type hints.
Here's another workaround... You could attach to autodoc-process-docstring and find "np." and replace it with "numpy.". That would then add a link to numpy.ndarray in your docs.
Here's another workaround... You could attach to autodoc-process-docstring and find "np." and replace it with "numpy.". That would then add a link to numpy.ndarray in your docs.
Do you have an example for that? I'd like to ensure that nn.Module (torch.nn.Module) and F.interpolate (torch.nn.functional.interpolate) redirect to the appropriate PyTorch docs, without having to type out the full path.
If you add autodoc_typehints = "short" to conf.py and do things like lines[i] = lines[i].replace("np.", "~numpy.") the hyperlinks will be shortened like below.
deffunc(self, val: np.ndarray) ->List[float]:
"""docstring of func Here is a detailed docstring. You know :func:`F.interpolate` is a cool function. Args: val (np.ndarray): Input argument Returns: List[float]: return value """pass
If you print the lines, you see exactly what is getting processed. If you only want to modify the types, you need to look for :type or :rtype at the beginning of a line.
reading sources... [ 50%] foo.func
foo.func
before: ['docstring of func', '', 'Here is a detailed docstring. You know :func:`F.interpolate` is a cool function.', '', ':param val: Input argument', ':type val: np.ndarray', '', ':returns: return value', ':rtype: List[float]', '']
after: ['docstring of func', '', 'Here is a detailed docstring. You know :func:`torch.nn.functional.interpolate` is a cool function.', '', ':param val: Input argument', ':type val: numpy.ndarray', '', ':returns: return value', ':rtype: ~typing.List[float]', '']
And it renders as below, with everything hyperlinked.
from typing import Callable
import torch
import torch.nn as nn
def test_func(x: torch.Tensor, test_module: nn.Module, test_fn: Callable) -> torch.Tensor:
"""
Description of function.
Args:
x (torch.Tensor): The input tensor.
test_module (nn.Module): The nn.Module instance to run x through.
test_fn (Callable): A callable class or function to pass x through.
Returns:
x (torch.Tensor): The output tensor.
"""
return test_module(test_fn(x))
My code uses doc strings like the one above, so I think that I could do something like this then (including increasing the specificity by targeting values inside / outside brackets, potentially with regex):
def autodoc_process_docstring(app, what, name, obj, options, lines):
parameters_docs = False:
for i in range(len(lines)):
if "Args:" in lines[i]:
parameters_docs = True
if not parameters_docs:
continue
lines[i] = lines[i].replace("nn.Module", "torch.nn.Module")
lines[i] = lines[i].replace("Callable[", "~typing.Callable[")
def setup(app):
app.connect("autodoc-process-docstring", autodoc_process_docstring)
You can't filter on "Args:". Sphinx converts the Google-style docstrings Args: and Returns: sections into rST syntax, which makes it even easier to filter. See my example in my previous post. You just need to look for :type or :rtype at the beginning of a line.
reading sources... [ 50%] foo.func
foo.func
before: ['docstring of func', '', 'Here is a detailed docstring. You know :func:`F.interpolate` is a cool function.', '', ':param val: Input argument', ':type val: np.ndarray', '', ':returns: return value', ':rtype: List[float]', '']
after: ['docstring of func', '', 'Here is a detailed docstring. You know :func:`torch.nn.functional.interpolate` is a cool function.', '', ':param val: Input argument', ':type val: numpy.ndarray', '', ':returns: return value', ':rtype: ~typing.List[float]', '']
You instead would want something like this:
foriinrange(len(lines)):
ifnot (lines[i].startswith(":type") orlines[i].startswith(":rtype")):
continue# Do stuff
I've discovered a new issue. When manually adding :obj: or :class: to the docstring types, they are no longer formatted as italics. Yet somehow Sphinx is able to implicitly hyperlink some of the types and italicize them when they are not manually specified with :obj: or :class:.
Thanks for the report. I retested this with Sphinx 9.1.1. Python annotations using np.ndarray resolve correctly because autodoc can inspect the imported object. However, types written in Napoleon docstrings are parsed as text, so intersphinx receives np.ndarray and cannot infer that np means numpy. The NumPy inventory only contains numpy.ndarray.
With this configuration, the warning disappears and the link to numpy.ndarray is generated. Because alias translation is already supported by napoleon_type_aliases, I'm closing this as answered.
Automatic inference of aliases from the documented object’s module should be tracked in a separate issue as a Napoleon enhancement.
Activity
ProGamerGov commentedon Jul 10, 2022
Was a solution ever found for this issue?
photoniker commentedon Jul 11, 2022
I didn't get any answer to this issue. So still open?!
ProGamerGov commentedon Jul 13, 2022
We might have to implement it ourselves via a PR.
This looks like the code for the extension: https://github.com/sphinx-doc/sphinx/blob/5.x/sphinx/ext/intersphinx.py
mhostetter commentedon Jul 13, 2022
I had this problem a while ago, which was why I subscribed to this thread. I found using type hints solves this problem. I don't know if it's worth it to you to switch, but... Also with proper type hints you can use the
autodoc-process-signaturecallback to further modify the presentation of the type hint signatures.Types in docstring
None of these are "clickable" except
float.Types as type hints
All of these are "clickable".
Conf.py
You can optionally add the
autodoc-process-signaturecallback if you'd like.photoniker commentedon Jul 15, 2022
OK I think I see the difference now. When you use a docstring generator as you have it in some python IDEs, it typically generates the docstring with the type included as it is defined in the docstring conventions: Numpy Docstring Format.
--> When you delete all typehints in the docstring, it works.
Does that mean the link to the numpy doc is overwritten?
mhostetter commentedon Jul 15, 2022
@photoniker how does this function render?
photoniker commentedon Jul 15, 2022
Seems to work with python build-in types
mhostetter commentedon Jul 15, 2022
That's a bummer. It appears that the docstring types supersede the function's actual annotations. I would've hoped for the opposite.
There's clearly an issue (as you reported) with how Napoleon processes types from the docstring. The workaround I've used is to simply remove types from the docstring and use type hints.
photoniker commentedon Jul 15, 2022
Removing the type hints in all my docstrings is quite a bit of work ;-)
mhostetter commentedon Jul 15, 2022
Here's another workaround... You could attach to
autodoc-process-docstringand find"np."and replace it with"numpy.". That would then add a link tonumpy.ndarrayin your docs.ProGamerGov commentedon Jul 15, 2022
Do you have an example for that? I'd like to ensure that
nn.Module(torch.nn.Module) andF.interpolate(torch.nn.functional.interpolate) redirect to the appropriate PyTorch docs, without having to type out the full path.mhostetter commentedon Jul 15, 2022
Below is an example with OPs function. The same trick can be applied to
nn.Moduletotorch.nn.Module.Here's the full example project. foo2-example.zip
Before
Notice
np.ndarrayisn't linked.After
Notice
np.ndarraywas converted tonumpy.ndarrayand is now linked.Shorten links
If you add
autodoc_typehints = "short"toconf.pyand do things likelines[i] = lines[i].replace("np.", "~numpy.")the hyperlinks will be shortened like below.ProGamerGov commentedon Jul 15, 2022
@mhostetter Thank you!
Is there an easy way to do something similar in the doc string and parameter descriptions as well?
Like making this:
Equivalent to this:
Or does your solution work on the entire doc string? If it works on the entire doc string, how can I only target the parameters?
mhostetter commentedon Jul 15, 2022
Yes, the entire docstring.
If you print the
lines, you see exactly what is getting processed. If you only want to modify the types, you need to look for:typeor:rtypeat the beginning of a line.And it renders as below, with everything hyperlinked.
ProGamerGov commentedon Jul 15, 2022
@mhostetter Ah, okay. Thanks for the help!
My code uses doc strings like the one above, so I think that I could do something like this then (including increasing the specificity by targeting values inside / outside brackets, potentially with regex):
mhostetter commentedon Jul 15, 2022
You can't filter on
"Args:". Sphinx converts the Google-style docstringsArgs:andReturns:sections into rST syntax, which makes it even easier to filter. See my example in my previous post. You just need to look for:typeor:rtypeat the beginning of a line.You instead would want something like this:
ProGamerGov commentedon Jul 25, 2022
@mhostetter You don't need to use
autodoc_typehints = "short", and you can change the link to say whatever you want.For example:
ProGamerGov commentedon Jul 30, 2022
I've discovered a new issue. When manually adding
:obj:or:class:to the docstring types, they are no longer formatted as italics. Yet somehow Sphinx is able to implicitly hyperlink some of the types and italicize them when they are not manually specified with:obj:or:class:.Is there anyway to fix this issue?
Edit:
This is an example of HTML code generated by Sphinx without explicitly defining the types:
And this is the same HTML, except for the bool variable being explicitly wrapped in
:class:bool``:The
<em>and</em>tags are missing in the second example for some reason.flying-sheep commentedon Mar 9, 2023
Would have been nice if my PR had been merged two years ago, then we wouldn’t need workarounds: #9039
HealthyPear commentedon May 9, 2023
Hello,
Not sure if my problem has the same root as yours, so before opening a duplicate issue I wanted to check.
In my project, I am using the traitlets library and basically aliasing their types in my package.
In their code, they do
import typing as tand they callt.Any,t.Dict, etc...then when I compile my docs I see warnings as
WARNING: py:class reference target not found: t.AnyIs this the same problem? Sphinx not able to "intersphinx" aliased modules?
jdillard commentedon Aug 25, 2026
Thanks for the report. I retested this with Sphinx 9.1.1. Python annotations using
np.ndarrayresolve correctly because autodoc can inspect the imported object. However, types written in Napoleon docstrings are parsed as text, so intersphinx receivesnp.ndarrayand cannot infer thatnpmeansnumpy. The NumPy inventory only containsnumpy.ndarray.This can be configured explicitly:
With this configuration, the warning disappears and the link to
numpy.ndarrayis generated. Because alias translation is already supported bynapoleon_type_aliases, I'm closing this as answered.Automatic inference of aliases from the documented object’s module should be tracked in a separate issue as a Napoleon enhancement.
flying-sheep commentedon Aug 25, 2026
@jdillard maybe someone can take up #9039, would be great if that got in in a more robust way