-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Description
Describe the bug
(It is probably easier to look at the reproduction, the screenshot, and the expected behavior than to read this description.)
In the following circumstances:
- A custom type is created with
typing.NewType - This type is autodocumented with the
autodatadirective - A function uses this custom type it its signature
- This function is autodocumented and types are rendered in the description
No link to the custom type is generated, even though Sphinx should be able to do so — and does so in some very similar cases.
Also, there are inconsistencies between the rendering of this particular case and some very similar cases, as shown below.
How to Reproduce
- Start a Sphinx project with default options of
sphinx-quickstart - Add to
conf.py:(I'm actually usingextensions = ['sphinx.ext.autodoc'] autodoc_typehints = 'both'
autodoc_typehints = "description"but setting it to"both"yields interesting observations.) - Create
mymodule.py:from __future__ import annotations from typing import NewType class A: """ This class is documented with ``autoclass``. It gets linked in the docstring of :func:`foo`. """ B = NewType("B", A) """ This type is documented with ``autoclass``. It gets linked in the docstring of :func:`foo`. However, Sphinx doesn't render its definition (alias of...) and displays it as "class mymodule.B(x)" rather than "mymodule.B". """ C = NewType("C", A) """ This type is documented with ``autodata``. Sphinx renders its definition (alias of...) However, it doesn't get linked in the docstring of :func:`foo`. """ def foo(a: A, b: B, c: C) -> None: """ Some function. :param a: first argument :param b: second argument :param c: third argument """
- Create
index.rst:.. automodule:: mymodule .. autoclass:: A .. autoclass:: B .. autodata:: C .. autofunction:: foo
- Run:
PYTHONPATH=. make html
- Open _build/html/index.hml
Expected behavior
Since A, B, and C are defined in the same module, I expect Sphinx to render their types consistently.
Currently:
- in the signature,
NewTypeinstances B and C render differently from regular class A (module name not shown vs. shown); I'm only seeing this in the minimal reproduction, not in my actual use case, so I don't really care; - in the description, there's the same issue, and further more the link to C isn't generated; this last problem is what bothers me most (because users just get a type name and don't even know whether it comes from the stdlib or my project, namely https://github.com/aaugustin/websockets)
Considering that:
- the documentation of C looks better than B;
- Sphinx is able to generate a link (it does so in the signature)
I believe that:
- autoattr is the way to go for
NewTypeinstances - the lack of a link is a bug
After a few hours of investigation, I suspect the link to C isn't generated because Sphinx looks up a xref of type "class", but C is documented as "data".
Indeed, this change causes the link to be generated (but obviously isn't the right fix):
diff --git a/sphinx/domains/python.py b/sphinx/domains/python.py
index e8330e81c..bc0667e2e 100644
--- a/sphinx/domains/python.py
+++ b/sphinx/domains/python.py
@@ -1113,7 +1113,7 @@ class PythonDomain(Domain):
label = 'Python'
object_types: Dict[str, ObjType] = {
'function': ObjType(_('function'), 'func', 'obj'),
- 'data': ObjType(_('data'), 'data', 'obj'),
+ 'data': ObjType(_('data'), 'data', 'class', 'obj'),
'class': ObjType(_('class'), 'class', 'exc', 'obj'),
'exception': ObjType(_('exception'), 'exc', 'class', 'obj'),
'method': ObjType(_('method'), 'meth', 'obj'),I think the right fix could be:
- generating xrefs of type "obj" for parameters types in description, so any Python object matches;
- failing that, generating xrefs for parameters types in description like in signature, since the latter appears to work as expected.
Your project
See "How to reproduce"
Screenshots
OS
Mac
Python version
3.10.0rc1+
Sphinx version
v4.2.0+/8fd4373d3
Sphinx extensions
sphinx.ext.autodoc
Extra tools
—
Additional context
—
