Skip to content

Commit

Permalink
Handle attrs forward refs (#345)
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
znicholls and pre-commit-ci[bot] authored Apr 13, 2023
1 parent ee0c649 commit 09197b8
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 1 deletion.
8 changes: 7 additions & 1 deletion src/sphinx_autodoc_typehints/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -359,12 +359,18 @@ def get_all_type_hints(autodoc_mock_imports: list[str], obj: Any, name: str) ->

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


def _resolve_type_guarded_imports(autodoc_mock_imports: list[str], obj: Any) -> None:
if hasattr(obj, "__module__") and obj.__module__ not in _TYPE_GUARD_IMPORTS_RESOLVED:
if (hasattr(obj, "__module__") and obj.__module__ not in _TYPE_GUARD_IMPORTS_RESOLVED) or (
hasattr(obj, "__globals__") and id(obj.__globals__) not in _TYPE_GUARD_IMPORTS_RESOLVED_GLOBALS_ID
):
_TYPE_GUARD_IMPORTS_RESOLVED.add(obj.__module__)
if obj.__module__ not in sys.builtin_module_names:
if hasattr(obj, "__globals__"):
_TYPE_GUARD_IMPORTS_RESOLVED_GLOBALS_ID.add(id(obj.__globals__))

module = inspect.getmodule(obj)
if module:
try:
Expand Down
9 changes: 9 additions & 0 deletions tests/roots/test-resolve-typing-guard-tmp/conf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import pathlib
import sys

master_doc = "index"
sys.path.insert(0, str(pathlib.Path(__file__).parent))
extensions = [
"sphinx.ext.autodoc",
"sphinx_autodoc_typehints",
]
59 changes: 59 additions & 0 deletions tests/roots/test-resolve-typing-guard-tmp/demo_typing_guard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
"""Module demonstrating imports that are type guarded"""
from __future__ import annotations

from typing import TYPE_CHECKING

from attrs import define

if TYPE_CHECKING:
import datetime


@define()
class SomeClass:
"""This class does something."""

date: datetime.date
"""Date to handle"""

@classmethod
def from_str(cls, input_value: str) -> SomeClass:
"""
Initialise from string
:param input_value: Input
:return: result
"""
return cls(input_value)

@classmethod
def from_date(cls, input_value: datetime.date) -> SomeClass:
"""
Initialise from date
:param input_value: Input
:return: result
"""
return cls(input_value)

@classmethod
def from_time(cls, input_value: datetime.time) -> SomeClass:
"""
Initialise from time
:param input_value: Input
:return: result
"""
return cls(input_value)

def calculate_thing(self, number: float) -> datetime.timedelta:
"""
Calculate a thing
:param number: Input
:return: result
"""
return datetime.timedelta(number)


__all__ = ["SomeClass"]
2 changes: 2 additions & 0 deletions tests/roots/test-resolve-typing-guard-tmp/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.. automodule:: demo_typing_guard
:members:
8 changes: 8 additions & 0 deletions tests/test_sphinx_autodoc_typehints.py
Original file line number Diff line number Diff line change
Expand Up @@ -754,6 +754,14 @@ def test_resolve_typing_guard_imports(app: SphinxTestApp, status: StringIO, warn
assert re.search(pat, err)


@pytest.mark.sphinx("text", testroot="resolve-typing-guard-tmp")
def test_resolve_typing_guard_attrs_imports(app: SphinxTestApp, status: StringIO, warning: StringIO) -> None:
set_python_path()
app.build()
assert "build succeeded" in status.getvalue()
assert not warning.getvalue()


def test_no_source_code_type_guard() -> None:
from csv import Error

Expand Down

0 comments on commit 09197b8

Please sign in to comment.