diff --git a/sphinx/ext/autodoc/importer.py b/sphinx/ext/autodoc/importer.py index 2082a714036..6a90c3da3fe 100644 --- a/sphinx/ext/autodoc/importer.py +++ b/sphinx/ext/autodoc/importer.py @@ -3,6 +3,7 @@ from __future__ import annotations import importlib +import sys import traceback import typing from typing import TYPE_CHECKING, Any, Callable, NamedTuple @@ -82,13 +83,18 @@ def import_object(modname: str, objpath: list[str], objtype: str = '', objpath = list(objpath) while module is None: try: + orig_modules = frozenset(sys.modules) try: # try importing with ``typing.TYPE_CHECKING == True`` typing.TYPE_CHECKING = True module = import_module(modname, warningiserror=warningiserror) except ImportError: # if that fails (e.g. circular import), retry with - # ``typing.TYPE_CHECKING == False`` + # ``typing.TYPE_CHECKING == False`` after reverting + # changes made to ``sys.modules`` by the failed try + for m in frozenset(sys.modules) - orig_modules: + sys.modules.pop(m) + typing.TYPE_CHECKING = False module = import_module(modname, warningiserror=warningiserror) finally: diff --git a/tests/roots/test-ext-autodoc/circular_import/__init__.py b/tests/roots/test-ext-autodoc/circular_import/__init__.py new file mode 100644 index 00000000000..402678d6706 --- /dev/null +++ b/tests/roots/test-ext-autodoc/circular_import/__init__.py @@ -0,0 +1 @@ +from circular_import.c import SomeClass diff --git a/tests/roots/test-ext-autodoc/circular_import/a.py b/tests/roots/test-ext-autodoc/circular_import/a.py new file mode 100644 index 00000000000..97ad9d8ab1b --- /dev/null +++ b/tests/roots/test-ext-autodoc/circular_import/a.py @@ -0,0 +1 @@ +X = 42 diff --git a/tests/roots/test-ext-autodoc/circular_import/b.py b/tests/roots/test-ext-autodoc/circular_import/b.py new file mode 100644 index 00000000000..c9b8ad54249 --- /dev/null +++ b/tests/roots/test-ext-autodoc/circular_import/b.py @@ -0,0 +1,4 @@ +import typing + +if typing.TYPE_CHECKING: + from circular_import import SomeClass diff --git a/tests/roots/test-ext-autodoc/circular_import/c.py b/tests/roots/test-ext-autodoc/circular_import/c.py new file mode 100644 index 00000000000..239b3acb37a --- /dev/null +++ b/tests/roots/test-ext-autodoc/circular_import/c.py @@ -0,0 +1,8 @@ +import circular_import.a +import circular_import.b + +assert hasattr(circular_import, "a") + + +class SomeClass: + X = circular_import.a.X diff --git a/tests/roots/test-ext-autodoc/index.rst b/tests/roots/test-ext-autodoc/index.rst index eb10829dcff..4f7378516da 100644 --- a/tests/roots/test-ext-autodoc/index.rst +++ b/tests/roots/test-ext-autodoc/index.rst @@ -13,3 +13,5 @@ .. autofunction:: target.overload.sum .. autofunction:: target.typehints.tuple_args + +.. automodule:: circular_import