From 81d4e1b0c0bcec190171b834bd86c1d07ce1ce2d Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Fri, 10 Nov 2023 12:34:49 -0800 Subject: [PATCH] ENH Make types in signature respect typehints_fully_qualified (#400) Resolves #351, resolves #389 --- src/sphinx_autodoc_typehints/__init__.py | 14 +++++--- tests/test_integration.py | 41 ++++++++++++++++++++++-- 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/sphinx_autodoc_typehints/__init__.py b/src/sphinx_autodoc_typehints/__init__.py index aa81b1f..a4f735a 100644 --- a/src/sphinx_autodoc_typehints/__init__.py +++ b/src/sphinx_autodoc_typehints/__init__.py @@ -367,10 +367,16 @@ def process_signature( # noqa: C901, PLR0913 start = 1 sph_signature = sph_signature.replace(parameters=parameters[start:]) - if not app.config.typehints_use_signature_return: - sph_signature = sph_signature.replace(return_annotation=inspect.Signature.empty) - - return stringify_signature(sph_signature).replace("\\", "\\\\"), None + show_return_annotation = app.config.typehints_use_signature_return + unqualified_typehints = not getattr(app.config, "typehints_fully_qualified", False) + return ( + stringify_signature( + sph_signature, + show_return_annotation=show_return_annotation, + unqualified_typehints=unqualified_typehints, + ).replace("\\", "\\\\"), + None, + ) def _is_dataclass(name: str, what: str, qualname: str) -> bool: diff --git a/tests/test_integration.py b/tests/test_integration.py index d1038c8..e5085fc 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -6,11 +6,21 @@ from inspect import isclass from pathlib import Path from textwrap import dedent, indent -from typing import TYPE_CHECKING, Any, Callable, NewType, Optional, TypeVar, Union, overload # no type comments +from typing import ( # no type comments + TYPE_CHECKING, + Any, + Callable, + NewType, + Optional, + TypeVar, + Union, + overload, +) import pytest if TYPE_CHECKING: + from collections.abc import AsyncGenerator from io import StringIO from mailbox import Mailbox from types import CodeType, ModuleType @@ -21,9 +31,10 @@ W = NewType("W", str) -def expected(expected: str) -> Callable[[T], T]: +def expected(expected: str, **options: dict[str, Any]) -> Callable[[T], T]: def dec(val: T) -> T: val.EXPECTED = expected + val.OPTIONS = options return val return dec @@ -1234,6 +1245,31 @@ def has_newtype(param: W) -> W: LT_PY310 = sys.version_info < (3, 10) +@expected( + """ + mod.typehints_use_signature(a: AsyncGenerator) -> AsyncGenerator + + Do something. + + Parameters: + **a** ("AsyncGenerator") -- blah + + Return type: + "AsyncGenerator" + + """, + typehints_use_signature=True, + typehints_use_signature_return=True, +) +def typehints_use_signature(a: AsyncGenerator) -> AsyncGenerator: + """Do something. + + Args: + a: blah + """ + return a + + @pytest.mark.parametrize("val", [x for x in globals().values() if hasattr(x, "EXPECTED")]) @pytest.mark.sphinx("text", testroot="integration") def test_integration( @@ -1251,6 +1287,7 @@ def test_integration( template = AUTO_FUNCTION (Path(app.srcdir) / "index.rst").write_text(template.format(val.__name__)) + app.config.__dict__.update(val.OPTIONS) monkeypatch.setitem(sys.modules, "mod", sys.modules[__name__]) app.build() assert "build succeeded" in status.getvalue() # Build succeeded