sphinx-doc / sphinx

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

from __future__ import annotations and autodoc_typehints = 'description' breaks type hint resolution #11674

Open robsdedude opened 10 months ago

robsdedude commented 10 months ago

Describe the bug

Turning https://github.com/sphinx-doc/sphinx/issues/10605#issuecomment-1199462450 into its own issue.

With autodoc_typehints = 'description' in the sphinx config and from __future__ import annotations in the Pythonfile, the parameter type annotations of the constructor (__init__) are not resolved correctly.

How to Reproduce

mylib.__init__.py

from __future__ import annotations

import typing as t

class Dummy:
    """
    :param arg: unresolved type hint
    """

    def __init__(self, arg: t.Optional[str]):
        pass

index.rst

.. autoclass:: mylib.Dummy

Sphinx conf.py

...
extensions = [
    'sphinx.ext.autodoc',
]

autodoc_typehints = "description"
...

This results in image

Removing from __future__ import annotations from mylib.__init__.py makes the problem go away image

Like wise does (only) removing autodoc_typehints = "description" from conf.py resolve the issue (even though it makes the type info appear in a different place as intended) image

Environment Information

Platform:              linux; (Linux-5.15.0-82-generic-x86_64-with-glibc2.35)
Python version:        3.10.12 (main, Jun 11 2023, 05:26:28) [GCC 11.4.0])
Python implementation: CPython
Sphinx version:        6.2.1
Docutils version:      0.19
Jinja2 version:        3.1.2
Pygments version:      2.16.1

Sphinx extensions

['sphinx.ext.autodoc']
picnixz commented 10 months ago
  1. IIUC, it only affect __init__ and possibly __new__, right?
  2. I know that the constructor is treated a bit differently because we allow param lists to be specified at the class level. It is very likely that we cannot resolve the forward reference at that point and then, when we want to resolve the type annotation, we are actually lacking the t in the local namespaces, leading to this bug.

I know where to look roughly but since I cannot do anything (or not much) with only my phone+termux, I will only be able to look at it in mid October.

In the meantime, you could try to specify a type alias using autodoc_type_aliases (check the doc for that). As I said in https://github.com/sphinx-doc/sphinx/issues/11652#issuecomment-1707736322, we can improve the type aliases map to handle those cases. Upon my return, I will draft an improvement of the latter in order to fix autodoc a bit more.

robsdedude commented 10 months ago
  1. exactly
  2. That's the conclusion I came to as well. You can have a look at the linked PR and you'll see that I proposed a fix for that: namely, emitting an event when the type annotations are being resolved so that the post processor can pick them up. But I understand that introducing an event just for that is not desirable.

Thanks for hinting me at autodoc_type_aliases. I shall have a look and see if it allows me to work around the problem.