Skip to content

Commit b5870e6

Browse files
authored
Extract the _docstring_source_name() function (#13972)
1 parent 1156555 commit b5870e6

File tree

2 files changed

+39
-29
lines changed

2 files changed

+39
-29
lines changed

doc/development/tutorials/examples/autodoc_intenum.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from typing import TYPE_CHECKING
55

66
from sphinx.ext.autodoc import ClassDocumenter, bool_option
7+
from sphinx.ext.autodoc._documenters import _docstring_source_name
78

89
if TYPE_CHECKING:
910
from typing import Any
@@ -31,27 +32,33 @@ def can_document_member(
3132
except TypeError:
3233
return False
3334

35+
def add_line(self, line: str, source: str = '', *lineno: int, indent: str) -> None:
36+
"""Append one line of generated reST to the output."""
37+
analyzer_source = '' if self.analyzer is None else self.analyzer.srcname
38+
source_name = _docstring_source_name(props=self.props, source=analyzer_source)
39+
if line.strip(): # not a blank line
40+
self.directive.result.append(indent + line, source_name, *lineno)
41+
else:
42+
self.directive.result.append('', source_name, *lineno)
43+
3444
def add_directive_header(self, *, indent: str) -> None:
3545
super().add_directive_header(indent=indent)
36-
self.add_line(' :final:', self.get_sourcename(), indent=indent)
46+
self.add_line(' :final:', indent=indent)
3747

3848
def add_content(self, more_content: StringList | None, *, indent: str) -> None:
3949
super().add_content(more_content, indent=indent)
4050

41-
source_name = self.get_sourcename()
4251
enum_object: IntEnum = self.props._obj
4352
use_hex = self.options.hex
44-
self.add_line('', source_name, indent=indent)
53+
self.add_line('', indent=indent)
4554

4655
for the_member_name, enum_member in enum_object.__members__.items(): # type: ignore[attr-defined]
4756
the_member_value = enum_member.value
4857
if use_hex:
4958
the_member_value = hex(the_member_value)
5059

51-
self.add_line(
52-
f'**{the_member_name}**: {the_member_value}', source_name, indent=indent
53-
)
54-
self.add_line('', source_name, indent=indent)
60+
self.add_line(f'**{the_member_name}**: {the_member_value}', indent=indent)
61+
self.add_line('', indent=indent)
5562

5663

5764
def setup(app: Sphinx) -> ExtensionMetadata:

sphinx/ext/autodoc/_documenters.py

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,8 @@ def add_directive_header(self, *, indent: str) -> None:
167167
is_final = False
168168

169169
result = self.directive.result
170-
sourcename = self.get_sourcename()
170+
analyzer_source = '' if self.analyzer is None else self.analyzer.srcname
171+
source_name = _docstring_source_name(props=self.props, source=analyzer_source)
171172
for line in _directive_header_lines(
172173
autodoc_typehints=self.config.autodoc_typehints,
173174
directive_name=directive_name,
@@ -176,27 +177,13 @@ def add_directive_header(self, *, indent: str) -> None:
176177
props=self.props,
177178
):
178179
if line.strip(): # not a blank line
179-
result.append(indent + line, sourcename)
180+
result.append(indent + line, source_name)
180181
else:
181-
result.append('', sourcename)
182-
183-
def get_sourcename(self) -> str:
184-
obj_module = inspect.safe_getattr(self.props._obj, '__module__', None)
185-
obj_qualname = inspect.safe_getattr(self.props._obj, '__qualname__', None)
186-
if obj_module and obj_qualname:
187-
# Get the correct location of docstring from props._obj
188-
# to support inherited methods
189-
fullname = f'{self.props._obj.__module__}.{self.props._obj.__qualname__}'
190-
else:
191-
fullname = self.props.full_name
192-
193-
if self.analyzer:
194-
return f'{self.analyzer.srcname}:docstring of {fullname}'
195-
else:
196-
return 'docstring of %s' % fullname
182+
result.append('', source_name)
197183

198184
def add_content(self, more_content: StringList | None, *, indent: str) -> None:
199185
"""Add content from docstrings, attribute documentation and user."""
186+
analyzer_source = '' if self.analyzer is None else self.analyzer.srcname
200187
# add content from docstrings
201188
processed_doc = StringList(
202189
list(
@@ -208,7 +195,7 @@ def add_content(self, more_content: StringList | None, *, indent: str) -> None:
208195
options=self.options,
209196
)
210197
),
211-
source=self.get_sourcename(),
198+
source=_docstring_source_name(props=self.props, source=analyzer_source),
212199
)
213200
_add_content(
214201
processed_doc,
@@ -451,16 +438,17 @@ def _generate(
451438
return
452439

453440
indent = self.indent
454-
sourcename = self.get_sourcename()
441+
analyzer_source = '' if self.analyzer is None else self.analyzer.srcname
442+
source_name = _docstring_source_name(props=self.props, source=analyzer_source)
455443

456444
# make sure that the result starts with an empty line. This is
457445
# necessary for some situations where another directive preprocesses
458446
# reST and no starting newline is present
459-
self.directive.result.append('', sourcename)
447+
self.directive.result.append('', source_name)
460448

461449
# generate the directive header and options, if applicable
462450
self.add_directive_header(indent=indent)
463-
self.directive.result.append('', sourcename)
451+
self.directive.result.append('', source_name)
464452

465453
# add all content (from docstrings, attribute docs etc.)
466454
self.add_content(more_content, indent=indent)
@@ -643,3 +631,18 @@ def __setattr__(self, key: str, value: Any) -> NoReturn:
643631
def __delattr__(self, key: str) -> NoReturn:
644632
msg = f'{self.__class__.__name__} is immutable'
645633
raise AttributeError(msg)
634+
635+
636+
def _docstring_source_name(*, props: _ItemProperties, source: str) -> str:
637+
obj_module = inspect.safe_getattr(props._obj, '__module__', None)
638+
obj_qualname = inspect.safe_getattr(props._obj, '__qualname__', None)
639+
if obj_module and obj_qualname:
640+
# Get the correct location of docstring from props._obj
641+
# to support inherited methods
642+
fullname = f'{obj_module}.{obj_qualname}'
643+
else:
644+
fullname = props.full_name
645+
646+
if source:
647+
return f'{source}:docstring of {fullname}'
648+
return f'docstring of {fullname}'

0 commit comments

Comments
 (0)