Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -259,8 +259,6 @@ module = [
"sphinx.ext.autodoc",
"sphinx.ext.autodoc.directive",
"sphinx.ext.autodoc.importer",
"sphinx.ext.autodoc.mock",
"sphinx.ext.autodoc.mock",
"sphinx.ext.autosummary.generate",
"sphinx.ext.doctest",
"sphinx.ext.graphviz",
Expand Down
13 changes: 7 additions & 6 deletions sphinx/ext/autodoc/mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@
from importlib.abc import Loader, MetaPathFinder
from importlib.machinery import ModuleSpec
from types import MethodType, ModuleType
from typing import TYPE_CHECKING, Any
from typing import TYPE_CHECKING

from sphinx.util import logging
from sphinx.util.inspect import isboundmethod, safe_getattr

if TYPE_CHECKING:
from collections.abc import Iterator, Sequence
from typing import Any

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -46,10 +47,10 @@ def __len__(self) -> int:
def __contains__(self, key: str) -> bool:
return False

def __iter__(self) -> Iterator:
return iter([])
def __iter__(self) -> Iterator[Any]:
return iter(())

def __mro_entries__(self, bases: tuple) -> tuple:
def __mro_entries__(self, bases: tuple[Any, ...]) -> tuple[type, ...]:
return (self.__class__,)

def __getitem__(self, key: Any) -> _MockObject:
Expand All @@ -68,7 +69,7 @@ def __repr__(self) -> str:


def _make_subclass(name: str, module: str, superclass: Any = _MockObject,
attributes: Any = None, decorator_args: tuple = ()) -> Any:
attributes: Any = None, decorator_args: tuple[Any, ...] = ()) -> Any:
attrs = {'__module__': module,
'__display_name__': module + '.' + name,
'__name__': name,
Expand Down Expand Up @@ -144,8 +145,8 @@ def mock(modnames: list[str]) -> Iterator[None]:
# mock modules are enabled here
...
"""
finder = MockFinder(modnames)
try:
finder = MockFinder(modnames)
sys.meta_path.insert(0, finder)
yield
finally:
Expand Down
16 changes: 16 additions & 0 deletions tests/test_extensions/test_ext_autodoc_automodule.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
source file translated by test_build.
"""

import inspect
import sys
import typing

import pytest

Expand Down Expand Up @@ -185,8 +187,22 @@ def test_automodule_inherited_members(app):
'sphinx.missing_module4']})
@pytest.mark.usefixtures("rollback_sysmodules")
def test_subclass_of_mocked_object(app):
from sphinx.ext.autodoc.mock import _MockObject
sys.modules.pop('target', None) # unload target module to clear the module cache

options = {'members': None}
actual = do_autodoc(app, 'module', 'target.need_mocks', options)
# ``typing.Any`` is not available at runtime on ``_MockObject.__new__``
assert '.. py:class:: Inherited(*args: Any, **kwargs: Any)' in actual

# make ``typing.Any`` available at runtime on ``_MockObject.__new__``
sig = inspect.signature(_MockObject.__new__)
parameters = sig.parameters.copy()
for name in ('args', 'kwargs'):
parameters[name] = parameters[name].replace(annotation=typing.Any)
sig = sig.replace(parameters=tuple(parameters.values()))
_MockObject.__new__.__signature__ = sig # type: ignore[attr-defined]

options = {'members': None}
actual = do_autodoc(app, 'module', 'target.need_mocks', options)
assert '.. py:class:: Inherited(*args: ~typing.Any, **kwargs: ~typing.Any)' in actual