sphinx-doc / sphinx

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

autodoc_typehints="description" doesn't fully resolve constructor type hints from type comments #8243

Open godlygeek opened 3 years ago

godlygeek commented 3 years ago

Describe the bug When autodoc_typehints="description", type hint comments for classes aren't fully resolved, even with autoclass_content="both".

To Reproduce Create module.py with these contents:

from typing import Optional

Maybe = Optional

class MaybeInt(object):
    """:param value: The value to hold"""
    def __init__(self, value):
        # type: (Maybe[int]) -> None
        self.value = value

    def get_value(self):
        # type: () -> Maybe[int]
        """:return: The held value"""
        return self.value

Create index.rst with these contents:

.. automodule:: module
   :members:

Generate docs twice in plain text format twice, once with autodoc_typehints="description" and once with autodoc_typehints="signature".

python3.8 -msphinx -aE -C -b text -D 'extensions=sphinx.ext.autodoc' -D autoclass_content=both -D autodoc_typehints=description . description
python3.8 -msphinx -aE -C -b text -D 'extensions=sphinx.ext.autodoc' -D autoclass_content=both -D autodoc_typehints=signature . signature

And note that signature/index.txt has:

class module.MaybeInt(value)

   Parameters:
      **value** (*Maybe**[**int**]*) -- The value to hold

   Return type:
      None

   get_value()

      Returns:
         The held value

      Return type:
         Optional[int]

In the case of the return type from get_value, the Maybe was resolved by typing.get_type_hints to be Optional. In the case of the parameter to the constructor, the Maybe was not able to be resolved.

When autodoc_typehints="signature", both were successfully resolved to Optional.

Expected behavior

Type hints should be fully resolved.

Environment info

Additional context

godlygeek commented 3 years ago

And, changing record_typehints to store the annotations of Person.__init__ for Person seems to work around the problem, though I'm not sure that's the right fix.