Skip to content

Commit fdf5411

Browse files
authored
Remove DocumenterBridge (#13984)
1 parent 6083b5a commit fdf5411

File tree

7 files changed

+113
-193
lines changed

7 files changed

+113
-193
lines changed

doc/development/tutorials/examples/autodoc_intenum.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ def add_line(self, line: str, source: str = '', *lineno: int, indent: str) -> No
3737
analyzer_source = '' if self.analyzer is None else self.analyzer.srcname
3838
source_name = _docstring_source_name(props=self.props, source=analyzer_source)
3939
if line.strip(): # not a blank line
40-
self.directive.result.append(indent + line, source_name, *lineno)
40+
self.result.append(indent + line, source_name, *lineno)
4141
else:
42-
self.directive.result.append('', source_name, *lineno)
42+
self.result.append('', source_name, *lineno)
4343

4444
def add_directive_header(self, *, indent: str) -> None:
4545
super().add_directive_header(indent=indent)

sphinx/ext/autodoc/_documenters.py

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
_ModuleProperties,
4343
_TypeStatementProperties,
4444
)
45-
from sphinx.ext.autodoc.directive import DocumenterBridge
45+
from sphinx.ext.autodoc.importer import _AttrGetter
4646
from sphinx.util.typing import OptionSpec, _RestifyMode
4747

4848
logger = logging.getLogger('sphinx.ext.autodoc')
@@ -86,26 +86,39 @@ class Documenter:
8686
}
8787

8888
def __init__(
89-
self, directive: DocumenterBridge, orig_name: str, indent: str = ''
89+
self,
90+
*,
91+
env: BuildEnvironment,
92+
options: _AutoDocumenterOptions,
93+
get_attr: _AttrGetter,
94+
record_dependencies: set[str] | None = None,
95+
result: StringList | None = None,
96+
indent: str = '',
9097
) -> None:
91-
self.directive = directive
92-
self.config: Config = directive.env.config
93-
self.env: BuildEnvironment = directive.env
94-
self._current_document: _CurrentDocument = directive.env.current_document
95-
self._events: EventManager = directive.env.events
96-
self.options: _AutoDocumenterOptions = directive.genopt
97-
self.get_attr = directive.get_attr
98-
self.orig_name = orig_name
98+
self.config: Config = env.config
99+
self.env: BuildEnvironment = env
100+
self._current_document: _CurrentDocument = env.current_document
101+
self._events: EventManager = env.events
102+
self.options: _AutoDocumenterOptions = options
103+
self.get_attr = get_attr
104+
if record_dependencies is not None:
105+
self.record_dependencies: set[str] = record_dependencies
106+
else:
107+
self.record_dependencies = set()
108+
if result is not None:
109+
self.result: StringList = result
110+
else:
111+
self.result = StringList()
99112
self.indent: Final = indent
100113
# the module analyzer to get at attribute docs, or None
101114
self.analyzer: ModuleAnalyzer | None = None
102115

103116
def add_line(self, line: str, source: str, *lineno: int, indent: str) -> None:
104117
"""Append one line of generated reST to the output."""
105118
if line.strip(): # not a blank line
106-
self.directive.result.append(indent + line, source, *lineno)
119+
self.result.append(indent + line, source, *lineno)
107120
else:
108-
self.directive.result.append('', source, *lineno)
121+
self.result.append('', source, *lineno)
109122

110123
def add_directive_header(self, *, indent: str) -> None:
111124
"""Add the directive header and options to the generated content."""
@@ -121,7 +134,7 @@ def add_directive_header(self, *, indent: str) -> None:
121134
else:
122135
is_final = False
123136

124-
result = self.directive.result
137+
result = self.result
125138
analyzer_source = '' if self.analyzer is None else self.analyzer.srcname
126139
source_name = _docstring_source_name(props=self.props, source=analyzer_source)
127140
for line in _directive_header_lines(
@@ -155,7 +168,7 @@ def add_content(self, more_content: StringList | None, *, indent: str) -> None:
155168
)
156169
_add_content(
157170
processed_doc,
158-
result=self.directive.result,
171+
result=self.result,
159172
indent=indent + ' ',
160173
)
161174

@@ -168,7 +181,7 @@ def add_content(self, more_content: StringList | None, *, indent: str) -> None:
168181
)
169182
_add_content(
170183
more_content,
171-
result=self.directive.result,
184+
result=self.result,
172185
indent=indent + ' ' * (self.props.obj_type != 'module'),
173186
)
174187

@@ -295,15 +308,15 @@ def _generate(
295308
and module_spec.has_location
296309
and module_spec.origin
297310
):
298-
self.directive.record_dependencies.add(module_spec.origin)
311+
self.record_dependencies.add(module_spec.origin)
299312
else:
300-
self.directive.record_dependencies.add(self.analyzer.srcname)
313+
self.record_dependencies.add(self.analyzer.srcname)
301314

302315
if self.real_modname != guess_modname:
303316
# Add module to dependency list if target object is defined in other module.
304317
try:
305318
srcname = ModuleAnalyzer.for_module(guess_modname).srcname
306-
self.directive.record_dependencies.add(srcname)
319+
self.record_dependencies.add(srcname)
307320
except PycodeError:
308321
pass
309322

@@ -330,11 +343,11 @@ def _generate(
330343
# make sure that the result starts with an empty line. This is
331344
# necessary for some situations where another directive preprocesses
332345
# reST and no starting newline is present
333-
self.directive.result.append('', source_name)
346+
self.result.append('', source_name)
334347

335348
# generate the directive header and options, if applicable
336349
self.add_directive_header(indent=indent)
337-
self.directive.result.append('', source_name)
350+
self.result.append('', source_name)
338351

339352
# add all content (from docstrings, attribute docs etc.)
340353
self.add_content(more_content, indent=indent)
@@ -349,14 +362,16 @@ def _generate(
349362
attr_docs=analyzer.attr_docs if analyzer is not None else {},
350363
config=self.config,
351364
current_document=self._current_document,
352-
directive=self.directive,
365+
env=self.env,
353366
events=self._events,
354367
get_attr=self.get_attr,
355368
indent=indent,
356369
options=self.options,
357370
props=self.props,
358371
real_modname=self.real_modname,
372+
record_dependencies=self.record_dependencies,
359373
registry=self.env._registry,
374+
result=self.result,
360375
)
361376

362377

sphinx/ext/autodoc/_member_finder.py

Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,11 @@
3232
from collections.abc import Iterable, Iterator, Mapping, Sequence, Set
3333
from typing import Any, Literal
3434

35+
from docutils.statemachine import StringList
36+
3537
from sphinx.config import Config
36-
from sphinx.environment import _CurrentDocument
38+
from sphinx.environment import BuildEnvironment, _CurrentDocument
3739
from sphinx.events import EventManager
38-
from sphinx.ext.autodoc import Documenter
3940
from sphinx.ext.autodoc._directive_options import _AutoDocumenterOptions
4041
from sphinx.ext.autodoc._property_types import _AutodocObjType, _ItemProperties
4142
from sphinx.ext.autodoc._sentinels import (
@@ -44,7 +45,6 @@
4445
INSTANCE_ATTR_T,
4546
SLOTS_ATTR_T,
4647
)
47-
from sphinx.ext.autodoc.directive import DocumenterBridge
4848
from sphinx.ext.autodoc.importer import _AttrGetter
4949
from sphinx.registry import SphinxComponentRegistry
5050

@@ -98,14 +98,16 @@ def _document_members(
9898
attr_docs: dict[tuple[str, str], list[str]],
9999
config: Config,
100100
current_document: _CurrentDocument,
101-
directive: DocumenterBridge,
101+
env: BuildEnvironment,
102102
events: EventManager,
103103
get_attr: _AttrGetter,
104104
indent: str,
105105
options: _AutoDocumenterOptions,
106106
props: _ItemProperties,
107107
real_modname: str,
108+
record_dependencies: set[str],
108109
registry: SphinxComponentRegistry,
110+
result: StringList,
109111
) -> None:
110112
"""Generate reST for member documentation.
111113
@@ -126,12 +128,11 @@ def _document_members(
126128
attr_docs=attr_docs,
127129
config=config,
128130
current_document=current_document,
129-
directive=directive,
131+
env=env,
130132
events=events,
131133
get_attr=get_attr,
132134
options=options,
133135
props=props,
134-
registry=registry,
135136
)
136137

137138
# for implicit module members, check __module__ to avoid
@@ -141,13 +142,23 @@ def _document_members(
141142
and want_all
142143
and (options.ignore_module_all or props.all is None) # type: ignore[attr-defined]
143144
)
144-
for documenter, is_attr in member_documenters:
145-
assert documenter.props.module_name
145+
for member_props, is_attr, member_indent in member_documenters:
146+
assert member_props.module_name
146147
# We can directly call ._generate() since the documenters
147148
# already called ``_load_object_by_name()`` before.
148149
#
149150
# Note that those two methods above do not emit events, so
150151
# whatever objects we deduced should not have changed.
152+
doccls = registry.documenters[member_props.obj_type]
153+
documenter = doccls(
154+
env=env,
155+
options=options,
156+
get_attr=get_attr,
157+
record_dependencies=record_dependencies,
158+
result=result,
159+
indent=member_indent,
160+
)
161+
documenter.props = member_props
151162
documenter._generate(
152163
all_members=True,
153164
real_modname=real_modname,
@@ -163,20 +174,17 @@ def _gather_members(
163174
attr_docs: dict[tuple[str, str], list[str]],
164175
config: Config,
165176
current_document: _CurrentDocument,
166-
directive: DocumenterBridge,
177+
env: BuildEnvironment,
167178
events: EventManager,
168179
get_attr: _AttrGetter,
169180
options: _AutoDocumenterOptions,
170181
props: _ItemProperties,
171-
registry: SphinxComponentRegistry,
172-
) -> list[tuple[Documenter, bool]]:
182+
) -> list[tuple[_ItemProperties, bool, str]]:
173183
"""Generate reST for member documentation.
174184
175185
If *want_all* is True, document all members, else those given by
176186
*self.options.members*.
177187
"""
178-
env = directive.env
179-
180188
if props.obj_type not in {'module', 'class', 'exception'}:
181189
msg = 'must be implemented in subclasses'
182190
raise NotImplementedError(msg)
@@ -220,7 +228,7 @@ def _gather_members(
220228
attr_docs=attr_docs,
221229
)
222230
# document non-skipped members
223-
member_documenters: list[tuple[Documenter, bool]] = []
231+
member_documenters: list[tuple[_ItemProperties, bool, str]] = []
224232
for member_name, member, is_attr in filtered_members:
225233
# prefer the documenter with the highest priority
226234
obj_type = _best_object_type_for_member(
@@ -251,16 +259,11 @@ def _gather_members(
251259
env=env,
252260
events=events,
253261
get_attr=get_attr,
254-
options=directive.genopt,
262+
options=options,
255263
)
256264
if member_props is None:
257265
continue
258-
259-
doccls = registry.documenters[obj_type]
260-
documenter = doccls(directive, full_name, indent)
261-
documenter.props = member_props
262-
263-
member_documenters.append((documenter, is_attr))
266+
member_documenters.append((member_props, is_attr, indent))
264267

265268
member_order = options.member_order or config.autodoc_member_order
266269
member_documenters = _sort_members(
@@ -653,18 +656,18 @@ def _best_object_type_for_member(
653656

654657

655658
def _sort_members(
656-
documenters: list[tuple[Documenter, bool]],
659+
documenters: list[tuple[_ItemProperties, bool, str]],
657660
order: Literal['alphabetical', 'bysource', 'groupwise'],
658661
*,
659662
ignore_module_all: bool,
660663
analyzer_order: dict[str, int],
661664
props: _ItemProperties,
662-
) -> list[tuple[Documenter, bool]]:
665+
) -> list[tuple[_ItemProperties, bool, str]]:
663666
"""Sort the given member list."""
664667
if order == 'groupwise':
665668
# sort by group; alphabetically within groups
666-
def group_order(entry: tuple[Documenter, bool]) -> tuple[int, str]:
667-
return entry[0].props._groupwise_order_key, entry[0].props.full_name
669+
def group_order(entry: tuple[_ItemProperties, bool, str]) -> tuple[int, str]:
670+
return entry[0]._groupwise_order_key, entry[0].full_name
668671

669672
documenters.sort(key=group_order)
670673
elif order == 'bysource':
@@ -677,8 +680,8 @@ def group_order(entry: tuple[Documenter, bool]) -> tuple[int, str]:
677680
module_all_idx = {name: idx for idx, name in enumerate(module_all)}
678681
module_all_len = len(module_all)
679682

680-
def source_order(entry: tuple[Documenter, bool]) -> int:
681-
fullname = entry[0].props.dotted_parts
683+
def source_order(entry: tuple[_ItemProperties, bool, str]) -> int:
684+
fullname = entry[0].dotted_parts
682685
return module_all_idx.get(fullname, module_all_len)
683686

684687
documenters.sort(key=source_order)
@@ -689,13 +692,13 @@ def source_order(entry: tuple[Documenter, bool]) -> int:
689692
# sort by source order, by virtue of the module analyzer
690693
order_len = len(analyzer_order)
691694

692-
def source_order(entry: tuple[Documenter, bool]) -> int:
693-
fullname = entry[0].props.dotted_parts
695+
def source_order(entry: tuple[_ItemProperties, bool, str]) -> int:
696+
fullname = entry[0].dotted_parts
694697
return analyzer_order.get(fullname, order_len)
695698

696699
documenters.sort(key=source_order)
697700
else: # alphabetical
698-
documenters.sort(key=lambda entry: entry[0].props.full_name)
701+
documenters.sort(key=lambda entry: entry[0].full_name)
699702

700703
return documenters
701704

0 commit comments

Comments
 (0)