Skip to content

Commit aba77c9

Browse files
committed
Fix annotation check exception (tox-dev#462)
Fix processing type aliases
1 parent 5894272 commit aba77c9

File tree

2 files changed

+49
-35
lines changed

2 files changed

+49
-35
lines changed

src/sphinx_autodoc_typehints/__init__.py

+20-12
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
from sphinx.util.inspect import signature as sphinx_signature
2121
from sphinx.util.inspect import stringify_signature
2222

23+
from typing import get_type_hints
24+
from sphinx.util.inspect import TypeAliasNamespace, TypeAliasForwardRef
25+
2326
from .parser import parse
2427
from .patches import install_patches
2528
from .version import __version__
@@ -194,6 +197,9 @@ def format_annotation(annotation: Any, config: Config) -> str: # noqa: C901, PL
194197
if isinstance(annotation, tuple):
195198
return format_internal_tuple(annotation, config)
196199

200+
if isinstance(annotation, TypeAliasForwardRef):
201+
return str(annotation)
202+
197203
try:
198204
module = get_annotation_module(annotation)
199205
class_name = get_annotation_class_name(annotation, module)
@@ -404,16 +410,19 @@ def _future_annotations_imported(obj: Any) -> bool:
404410
return bool(_annotations.compiler_flag == future_annotations)
405411

406412

407-
def get_all_type_hints(autodoc_mock_imports: list[str], obj: Any, name: str) -> dict[str, Any]:
408-
result = _get_type_hint(autodoc_mock_imports, name, obj)
413+
def get_all_type_hints(
414+
autodoc_mock_imports: list[str], obj: Any, name: str, localns: TypeAliasNamespace
415+
) -> dict[str, Any]:
416+
417+
result = _get_type_hint(autodoc_mock_imports, name, obj, localns)
409418
if not result:
410419
result = backfill_type_hints(obj, name)
411420
try:
412421
obj.__annotations__ = result
413422
except (AttributeError, TypeError):
414423
pass
415424
else:
416-
result = _get_type_hint(autodoc_mock_imports, name, obj)
425+
result = _get_type_hint(autodoc_mock_imports, name, obj, localns)
417426
return result
418427

419428

@@ -474,10 +483,12 @@ def _resolve_type_guarded_imports(autodoc_mock_imports: list[str], obj: Any) ->
474483
_execute_guarded_code(autodoc_mock_imports, obj, module_code)
475484

476485

477-
def _get_type_hint(autodoc_mock_imports: list[str], name: str, obj: Any) -> dict[str, Any]:
486+
def _get_type_hint(
487+
autodoc_mock_imports: list[str], name: str, obj: Any, localns: TypeAliasForwardRef
488+
) -> dict[str, Any]:
478489
_resolve_type_guarded_imports(autodoc_mock_imports, obj)
479490
try:
480-
result = get_type_hints(obj)
491+
result = get_type_hints(obj, None, localns)
481492
except (AttributeError, TypeError, RecursionError) as exc:
482493
# TypeError - slot wrapper, PEP-563 when part of new syntax not supported
483494
# RecursionError - some recursive type definitions https://github.com/python/typing/issues/574
@@ -645,7 +656,9 @@ def process_docstring( # noqa: PLR0913, PLR0917
645656
signature = sphinx_signature(obj, type_aliases=app.config["autodoc_type_aliases"])
646657
except (ValueError, TypeError):
647658
signature = None
648-
type_hints = get_all_type_hints(app.config.autodoc_mock_imports, obj, name)
659+
660+
localns = TypeAliasNamespace(app.config["autodoc_type_aliases"])
661+
type_hints = get_all_type_hints(app.config.autodoc_mock_imports, obj, name, localns)
649662
app.config._annotation_globals = getattr(obj, "__globals__", {}) # type: ignore[attr-defined] # noqa: SLF001
650663
try:
651664
_inject_types_to_docstring(type_hints, signature, original_obj, app, what, name, lines)
@@ -715,14 +728,9 @@ def _inject_signature( # noqa: C901
715728
app: Sphinx,
716729
lines: list[str],
717730
) -> None:
718-
type_aliases = app.config["autodoc_type_aliases"]
719731

720732
for arg_name, arg_type in signature.parameters.items():
721-
annotation = (
722-
ForwardRef(arg_type.annotation, is_argument=True, is_class=False)
723-
if str(arg_type.annotation) in type_aliases
724-
else type_hints.get(arg_name)
725-
)
733+
annotation = type_hints.get(arg_name)
726734

727735
default = signature.parameters[arg_name].default
728736

tests/test_integration_autodoc_type_aliases.py

+29-23
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,7 @@ def dec(val: T) -> T:
3434
return dec
3535

3636

37-
from numpy.typing import ArrayLike
38-
39-
# ArrayLike = Literal["test"]
37+
ArrayLike = Literal["test"]
4038

4139

4240
class _SchemaMeta(type):
@@ -71,14 +69,40 @@ def f(s: Schema) -> Schema:
7169
return s
7270

7371

72+
class AliasedClass: ...
73+
74+
75+
@expected(
76+
"""
77+
mod.g(s)
78+
79+
Do something.
80+
81+
Parameters:
82+
**s** ("Class Alias") -- Some schema.
83+
84+
Return type:
85+
"Class Alias"
86+
"""
87+
)
88+
def g(s: AliasedClass) -> AliasedClass:
89+
"""
90+
Do something.
91+
92+
Args:
93+
s: Some schema.
94+
"""
95+
return s
96+
97+
7498
@expected(
7599
"""\
76100
mod.function(x, y)
77101
78102
Function docstring.
79103
80104
Parameters:
81-
* **x** (ArrayLike) -- foo
105+
* **x** (Array) -- foo
82106
83107
* **y** ("Schema") -- boo
84108
@@ -103,25 +127,7 @@ def function(x: ArrayLike, y: Schema) -> str: # noqa: ARG001
103127

104128
# Config settings for each test run.
105129
# Config Name: Sphinx Options as Dict.
106-
configs = {
107-
"default_conf": {
108-
"autodoc_type_aliases": {
109-
"ArrayLike": "ArrayLike",
110-
}
111-
}
112-
}
113-
# typehints_use_signature
114-
# typehints_defaults
115-
# typehints_fully_qualified = False
116-
# always_document_param_types = False
117-
# always_use_bars_union = False
118-
# typehints_document_rtype = True
119-
# typehints_use_rtype = True
120-
# typehints_defaults = "comma"
121-
# simplify_optional_unions = True
122-
# typehints_formatter = None
123-
# typehints_use_signature = True
124-
# typehints_use_signature_return = True
130+
configs = {"default_conf": {"autodoc_type_aliases": {"ArrayLike": "Array", "AliasedClass": '"Class Alias"'}}}
125131

126132

127133
@pytest.mark.parametrize("val", [x for x in globals().values() if hasattr(x, "EXPECTED")])

0 commit comments

Comments
 (0)