sphinx-doc / sphinx

The Sphinx documentation generator
https://www.sphinx-doc.org/
Other
6.64k stars 2.13k forks source link

Inconsistent type references when using autodoc #7972

Open CarstenLeue opened 4 years ago

CarstenLeue commented 4 years ago

Describe the bug

I have the following python code:

"""My Implementation"""
from typing import Collection

from sphinx_autodoc.api import MyInterfaceClass

class MyClass:  # pylint: disable=too-few-public-methods
    """This is my class and its doc

    This is a reference to :class:`~sphinx_autodoc.api.MyInterfaceClass`

    """

    delegate: MyInterfaceClass
    """Some delegate"""

    external: Collection
    """Some external reference"""

    def get_delegate(self) -> MyInterfaceClass:
        """Gets the delegate

        Returns:
            the delegate
        """
        return self.delegate

    def get_external(self) -> Collection:
        """Gets the delegate

        Returns:
            the delegate
        """
        return self.external

VARIABLE: MyClass = MyClass()
"""This is my variable and its doc"""

When producing a Sphinx documentation with the following config:

extensions = [
    'sphinx.ext.intersphinx',
    'sphinx.ext.napoleon',
    'sphinx_autodoc_typehints',
    'sphinx.ext.autodoc'
]

# Some config
intersphinx_mapping = {'python': ('https://docs.python.org/3', None)}

I see the following unexpected behaviour:

To Reproduce

I have created a small test repo to illustrate and reproduce the issue:

The result of this step is also checked in at https://github.com/Carsten-Leue/sphinx-autodoc/tree/master/build/docs

Expected behavior

Your project

https://github.com/Carsten-Leue/sphinx-autodoc

Environment info

tk0miya commented 4 years ago

the global property VARIABLE does not appear in the documentation at all

This happens for imported variables. At present, autodoc can detect global-level variable only assigned at the module (addition to this, comment or string is needed around the assignment). I don't have a way for this.

there is no link at all on the documentation of the type of the instance propery delegate

This must be a bug. I'll take a look later.

the styling of the the type of the instance propery delegate visually does not look like the styling for the same type on the return value of get_delegate

This is a problem of sphinx_rtd_theme. So please report it to them. If you use Sphinx's default theme; alabaster, you'll see the types as follows.

スクリーンショット 2020-07-19 17 47 12

there is no link at all on the documentation of the type of the instance propery external

Same as delegate's case.

the documentation of the function get_delegate() shows the correct return type but there is no link on that type to the documentation

Similart to delegate. But they are different internally. Autodoc generates the following reST internally from the code:

   .. py:method:: MyClass.get_delegate()
      :module: sphinx_autodoc

      Gets the delegate

      :rtype: :py:class:`~sphinx_autodoc.api._internal.impl.MyInterfaceClass`
      :returns: the delegate

sphinx_autodoc.api._internal.impl.MyInterfaceClass is where the class is defined in real. But this document only provides a doc for sphinx_autodoc.api.MyInterfaceClass instead. So it failed to create a link.

CarstenLeue commented 4 years ago

This happens for imported variables. At present, autodoc can detect global-level variable only assigned at the module (addition to this, comment or string is needed around the assignment). I don't have a way for this.

The variable is referenced in the __all__ export of the documented module: https://github.com/Carsten-Leue/sphinx-autodoc/blob/master/sphinx_autodoc/__init__.py#L10 Wouldn't it be possible to use this list as the reference and then follow the imports to locate the variable and its attached docstring?

sphinx_autodoc.api._internal.impl.MyInterfaceClass is where the class is defined in real. But this document only provides a doc for sphinx_autodoc.api.MyInterfaceClass instead. So it failed to create a link.

I understand. However shouldn't the documentation refer to the classes (and variables) via their public exports instead of their implementation details? The class sphinx_autodoc.api.MyInterfaceClass is the public alias of the implementation class sphinx_autodoc.api._internal.impl.MyInterfaceClass and autodoc correctly generates documentation of this public class. I think that it would make sense that autodoc maps all aliases of this class to the publically exported classs.

In the example the class is imported via it's public alias https://github.com/Carsten-Leue/sphinx-autodoc/blob/master/sphinx_autodoc/_internal/impl.py#L4, so there must already be some mapping between aliases. This mapping probably points to the implementation class at the moment, I wonder if this could be changed to point to the public export instead.

tk0miya commented 4 years ago

Thank you for your great advice. At present, autodoc can't do them all. So I'll wait for your great pull request.

tk0miya commented 4 years ago

there is no link at all on the documentation of the type of the instance propery delegate

I noticed the delegate's case is the same as get_delegate(). So the big rewriting is needed to support it.