Skip to content

Commit 09197b8

Browse files
Handle attrs forward refs (#345)
* Add failing test * Pass test * Alternate solution * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Pre-commit --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent ee0c649 commit 09197b8

File tree

5 files changed

+85
-1
lines changed

5 files changed

+85
-1
lines changed

src/sphinx_autodoc_typehints/__init__.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,12 +359,18 @@ def get_all_type_hints(autodoc_mock_imports: list[str], obj: Any, name: str) ->
359359

360360
_TYPE_GUARD_IMPORT_RE = re.compile(r"\nif (typing.)?TYPE_CHECKING:[^\n]*([\s\S]*?)(?=\n\S)")
361361
_TYPE_GUARD_IMPORTS_RESOLVED = set()
362+
_TYPE_GUARD_IMPORTS_RESOLVED_GLOBALS_ID = set()
362363

363364

364365
def _resolve_type_guarded_imports(autodoc_mock_imports: list[str], obj: Any) -> None:
365-
if hasattr(obj, "__module__") and obj.__module__ not in _TYPE_GUARD_IMPORTS_RESOLVED:
366+
if (hasattr(obj, "__module__") and obj.__module__ not in _TYPE_GUARD_IMPORTS_RESOLVED) or (
367+
hasattr(obj, "__globals__") and id(obj.__globals__) not in _TYPE_GUARD_IMPORTS_RESOLVED_GLOBALS_ID
368+
):
366369
_TYPE_GUARD_IMPORTS_RESOLVED.add(obj.__module__)
367370
if obj.__module__ not in sys.builtin_module_names:
371+
if hasattr(obj, "__globals__"):
372+
_TYPE_GUARD_IMPORTS_RESOLVED_GLOBALS_ID.add(id(obj.__globals__))
373+
368374
module = inspect.getmodule(obj)
369375
if module:
370376
try:
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import pathlib
2+
import sys
3+
4+
master_doc = "index"
5+
sys.path.insert(0, str(pathlib.Path(__file__).parent))
6+
extensions = [
7+
"sphinx.ext.autodoc",
8+
"sphinx_autodoc_typehints",
9+
]
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
"""Module demonstrating imports that are type guarded"""
2+
from __future__ import annotations
3+
4+
from typing import TYPE_CHECKING
5+
6+
from attrs import define
7+
8+
if TYPE_CHECKING:
9+
import datetime
10+
11+
12+
@define()
13+
class SomeClass:
14+
"""This class does something."""
15+
16+
date: datetime.date
17+
"""Date to handle"""
18+
19+
@classmethod
20+
def from_str(cls, input_value: str) -> SomeClass:
21+
"""
22+
Initialise from string
23+
24+
:param input_value: Input
25+
:return: result
26+
"""
27+
return cls(input_value)
28+
29+
@classmethod
30+
def from_date(cls, input_value: datetime.date) -> SomeClass:
31+
"""
32+
Initialise from date
33+
34+
:param input_value: Input
35+
:return: result
36+
"""
37+
return cls(input_value)
38+
39+
@classmethod
40+
def from_time(cls, input_value: datetime.time) -> SomeClass:
41+
"""
42+
Initialise from time
43+
44+
:param input_value: Input
45+
:return: result
46+
"""
47+
return cls(input_value)
48+
49+
def calculate_thing(self, number: float) -> datetime.timedelta:
50+
"""
51+
Calculate a thing
52+
53+
:param number: Input
54+
:return: result
55+
"""
56+
return datetime.timedelta(number)
57+
58+
59+
__all__ = ["SomeClass"]
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.. automodule:: demo_typing_guard
2+
:members:

tests/test_sphinx_autodoc_typehints.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,14 @@ def test_resolve_typing_guard_imports(app: SphinxTestApp, status: StringIO, warn
754754
assert re.search(pat, err)
755755

756756

757+
@pytest.mark.sphinx("text", testroot="resolve-typing-guard-tmp")
758+
def test_resolve_typing_guard_attrs_imports(app: SphinxTestApp, status: StringIO, warning: StringIO) -> None:
759+
set_python_path()
760+
app.build()
761+
assert "build succeeded" in status.getvalue()
762+
assert not warning.getvalue()
763+
764+
757765
def test_no_source_code_type_guard() -> None:
758766
from csv import Error
759767

0 commit comments

Comments
 (0)