Skip to content

Commit b9d5d2b

Browse files
authored
Reduce autodoc test duration by up to four times (#14039)
1 parent 9eb3d79 commit b9d5d2b

17 files changed

+1389
-1476
lines changed

sphinx/ext/autodoc/_directive_options.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ def __getattr__(self, name: str) -> Any:
241241
def _process_documenter_options(
242242
*,
243243
obj_type: _AutodocObjType,
244-
default_options: dict[str, str | bool],
244+
default_options: Mapping[str, str | bool],
245245
options: dict[str, str | None],
246246
) -> _AutoDocumenterOptions:
247247
"""Recognize options of object type from user input."""
Lines changed: 57 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,70 @@
11
from __future__ import annotations
22

3+
from types import SimpleNamespace
34
from typing import TYPE_CHECKING
45

56
from docutils.statemachine import StringList
67

7-
from sphinx.ext.autodoc._directive_options import (
8-
_process_documenter_options,
9-
)
8+
from sphinx.environment import _CurrentDocument
9+
from sphinx.events import EventManager
10+
from sphinx.ext.autodoc._directive_options import _process_documenter_options
1011
from sphinx.ext.autodoc._generate import _generate_directives
1112
from sphinx.ext.autodoc._loader import _load_object_by_name
1213
from sphinx.ext.autodoc._shared import _AutodocConfig
1314
from sphinx.util.inspect import safe_getattr
1415

1516
if TYPE_CHECKING:
17+
from collections.abc import Callable, Mapping
1618
from typing import Any
1719

18-
from sphinx.application import Sphinx
1920
from sphinx.ext.autodoc._property_types import _AutodocObjType
2021

22+
_DEFAULT_CONFIG = _AutodocConfig()
23+
24+
25+
class FakeEvents(EventManager):
26+
def __init__(self) -> None:
27+
super().__init__(SimpleNamespace(pdb=False)) # type: ignore[arg-type]
28+
29+
self.add('autodoc-before-process-signature')
30+
self.add('autodoc-process-docstring')
31+
self.add('autodoc-process-signature')
32+
self.add('autodoc-skip-member')
33+
self.add('autodoc-process-bases')
34+
self.add('object-description-transform')
35+
36+
def connect(
37+
self, name: str, callback: Callable[..., Any], priority: int = 500
38+
) -> int:
39+
return super().connect(name, callback, priority)
40+
2141

2242
def do_autodoc(
23-
app: Sphinx,
2443
obj_type: _AutodocObjType,
2544
name: str,
45+
*,
46+
config: _AutodocConfig = _DEFAULT_CONFIG,
47+
current_document: _CurrentDocument | None = None,
48+
events: FakeEvents | None = None,
49+
expect_import_error: bool = False,
2650
options: dict[str, Any] | None = None,
51+
ref_context: Mapping[str, str | None] | None = None,
2752
) -> list[str]:
53+
if current_document is None:
54+
current_document = _CurrentDocument(docname='index')
55+
if events is None:
56+
events = FakeEvents()
57+
if ref_context is None:
58+
ref_context = {}
59+
reread_always: set[str] = set()
60+
2861
options = {} if options is None else options.copy()
29-
if not app.env.current_document.docname:
30-
app.env.current_document.docname = 'index' # set dummy docname
3162
doc_options = _process_documenter_options(
3263
obj_type=obj_type,
33-
default_options=app.config.autodoc_default_options,
64+
default_options=config.autodoc_default_options,
3465
options=options,
3566
)
3667

37-
config = _AutodocConfig.from_config(app.config)
38-
current_document = app.env.current_document
39-
events = app.events
40-
ref_context = app.env.ref_context
41-
reread_always: set[str] = set()
4268
props = _load_object_by_name(
4369
name=name,
4470
objtype=obj_type,
@@ -50,19 +76,23 @@ def do_autodoc(
5076
ref_context=ref_context,
5177
reread_always=reread_always,
5278
)
79+
if expect_import_error:
80+
assert props is None
81+
return []
82+
83+
assert props is not None
5384
result = StringList()
54-
if props is not None:
55-
_generate_directives(
56-
config=config,
57-
current_document=current_document,
58-
events=events,
59-
get_attr=safe_getattr,
60-
indent='',
61-
options=doc_options,
62-
props=props,
63-
record_dependencies=set(),
64-
ref_context=ref_context,
65-
reread_always=reread_always,
66-
result=result,
67-
)
85+
_generate_directives(
86+
config=config,
87+
current_document=current_document,
88+
events=events,
89+
get_attr=safe_getattr,
90+
indent='',
91+
options=doc_options,
92+
props=props,
93+
record_dependencies=set(),
94+
ref_context=ref_context,
95+
reread_always=reread_always,
96+
result=result,
97+
)
6898
return result.data

tests/test_ext_autodoc/conftest.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
from __future__ import annotations
2+
3+
import sys
4+
5+
import pytest
6+
7+
from tests.utils import TEST_ROOTS_DIR
8+
9+
TYPE_CHECKING = False
10+
if TYPE_CHECKING:
11+
from collections.abc import Iterator
12+
13+
14+
@pytest.fixture(scope='module')
15+
def inject_autodoc_root_into_sys_path() -> Iterator[None]:
16+
autodoc_root_path = str(TEST_ROOTS_DIR / 'test-ext-autodoc')
17+
18+
sys.path.insert(0, autodoc_root_path)
19+
yield
20+
sys.path[:] = [p for p in sys.path if p != autodoc_root_path]

0 commit comments

Comments
 (0)