1616from sphinx .util .inspect import getdoc
1717
1818if TYPE_CHECKING :
19- from collections .abc import Iterator , Mapping , Sequence
19+ from collections .abc import Iterator , Mapping
2020 from typing import Any , Literal
2121
2222 from sphinx .events import EventManager
2626
2727logger = logging .getLogger ('sphinx.ext.autodoc' )
2828
29- _OBJECT_INIT_DOCSTRING = (tuple (prepare_docstring (object .__init__ .__doc__ or '' )),)
30- _OBJECT_NEW_DOCSTRING = (tuple (prepare_docstring (object .__new__ .__doc__ or '' )),)
29+ _OBJECT_INIT_DOCSTRING = [prepare_docstring (object .__init__ .__doc__ or '' )]
30+ _OBJECT_NEW_DOCSTRING = [prepare_docstring (object .__new__ .__doc__ or '' )]
31+
32+
33+ def _docstring_lines_for_props (
34+ docstrings : list [list [str ]] | None ,
35+ / ,
36+ * ,
37+ props : _ItemProperties ,
38+ real_modname : str | None ,
39+ events : EventManager ,
40+ options : _AutoDocumenterOptions ,
41+ ) -> tuple [str , ...]:
42+ guess_modname = props ._obj___module__ or props .module_name
43+ if props .obj_type in {'class' , 'exception' }:
44+ # Do not pass real_modname and use the name from the __module__
45+ # attribute of the class.
46+ # If a class gets imported into the module real_modname
47+ # the analyzer won't find the source of the class, if
48+ # it looks in real_modname.
49+ real_modname = guess_modname
50+ else :
51+ real_modname = real_modname or guess_modname
52+ try :
53+ analyzer = ModuleAnalyzer .for_module (real_modname )
54+ # parse right now, to get PycodeErrors on parsing (results will
55+ # be cached anyway)
56+ analyzer .analyze ()
57+ except PycodeError as exc :
58+ logger .debug ('[autodoc] module analyzer failed: %s' , exc )
59+ # no source file -- e.g. for builtin and C modules
60+ analyzer = None
61+
62+ attr_docs = {} if analyzer is None else analyzer .attr_docs
63+ prepared_docstrings = _prepare_docstrings (
64+ docstrings , props = props , attr_docs = attr_docs
65+ )
66+ docstring_lines = _process_docstrings (
67+ prepared_docstrings ,
68+ events = events ,
69+ props = props ,
70+ options = options ,
71+ )
72+ return tuple (docstring_lines )
3173
3274
3375def _prepare_docstrings (
76+ docstrings : list [list [str ]] | None ,
3477 * ,
3578 props : _ItemProperties ,
3679 attr_docs : Mapping [tuple [str , str ], list [str ]],
3780) -> list [list [str ]] | None :
3881 """Add content from docstrings, attribute documentation and user."""
39- if props ._docstrings is not None :
40- if props ._docstrings :
41- docstrings = [list (doc ) for doc in props ._docstrings ]
42- else :
43- # append at least a dummy docstring, so that the event
44- # autodoc-process-docstring is fired and can add some
45- # content if desired
46- docstrings = [[]]
47- else :
48- docstrings = None
82+ if docstrings is not None and not docstrings :
83+ # append at least a dummy docstring, so that the event
84+ # autodoc-process-docstring is fired and can add some
85+ # content if desired
86+ docstrings = [[]]
4987
5088 if props .obj_type in {'data' , 'attribute' }:
5189 return docstrings
@@ -107,29 +145,24 @@ def _get_docstring_lines(
107145 inherit_docstrings : bool ,
108146 parent : Any ,
109147 tab_width : int ,
110- _new_docstrings : Sequence [Sequence [str ]] | None = None ,
111- ) -> Sequence [Sequence [str ]] | None :
148+ ) -> list [list [str ]] | None :
112149 obj = props ._obj
113150
114151 if props .obj_type in {'class' , 'exception' }:
115152 assert isinstance (props , _ClassDefProperties )
116153
117154 if isinstance (obj , TypeVar ):
118155 if obj .__doc__ == TypeVar .__doc__ :
119- return ()
156+ return []
120157 if props .doc_as_attr :
121158 # Don't show the docstring of the class when it is an alias.
122159 if _class_variable_comment (props ):
123- return ()
160+ return []
124161 return None
125162
126- if _new_docstrings is not None :
127- return tuple (tuple (doc ) for doc in _new_docstrings )
128-
129163 docstrings = []
130- attrdocstring = getdoc (obj )
131- if attrdocstring :
132- docstrings .append (attrdocstring )
164+ if attr_docstring := getdoc (obj ):
165+ docstrings .append (attr_docstring )
133166
134167 # for classes, what the "docstring" is can be controlled via a
135168 # config value; the default is only the class docstring
@@ -162,25 +195,20 @@ def _get_docstring_lines(
162195 else :
163196 docstrings .append (init_docstring )
164197
165- return tuple (
166- tuple (prepare_docstring (docstring , tab_width )) for docstring in docstrings
167- )
198+ return [prepare_docstring (docstring , tab_width ) for docstring in docstrings ]
168199
169200 if props .obj_type == 'method' :
170201 docstring = _get_doc (
171202 obj ,
172203 props = props ,
173204 inherit_docstrings = inherit_docstrings ,
174- _new_docstrings = _new_docstrings ,
175205 parent = parent ,
176206 tab_width = tab_width ,
177207 )
178- if props .name == '__init__' :
179- if docstring == _OBJECT_INIT_DOCSTRING :
180- return ()
181- if props .name == '__new__' :
182- if docstring == _OBJECT_NEW_DOCSTRING :
183- return ()
208+ if props .name == '__init__' and docstring == _OBJECT_INIT_DOCSTRING :
209+ return []
210+ if props .name == '__new__' and docstring == _OBJECT_NEW_DOCSTRING :
211+ return []
184212 return docstring
185213
186214 if props .obj_type == 'data' :
@@ -193,17 +221,16 @@ def _get_docstring_lines(
193221 analyzer .analyze ()
194222 key = ('' , props .name )
195223 if key in analyzer .attr_docs :
196- comment = tuple (analyzer .attr_docs [key ])
224+ comment = list (analyzer .attr_docs [key ])
197225 except PycodeError :
198226 pass
199227
200228 if comment :
201- return ( comment ,)
229+ return [ comment ]
202230 return _get_doc (
203231 obj ,
204232 props = props ,
205233 inherit_docstrings = inherit_docstrings ,
206- _new_docstrings = _new_docstrings ,
207234 parent = parent ,
208235 tab_width = tab_width ,
209236 )
@@ -219,7 +246,7 @@ def _get_docstring_lines(
219246 parent = parent , obj_path = props .parts , attrname = props .parts [- 1 ]
220247 )
221248 if comment :
222- return ( comment ,)
249+ return [ comment ]
223250
224251 # Disable `autodoc_inherit_docstring` to avoid to obtain
225252 # a docstring from the value which descriptor returns unexpectedly.
@@ -231,16 +258,15 @@ def _get_docstring_lines(
231258 try :
232259 parent___slots__ = inspect .getslots (parent )
233260 if parent___slots__ and (docstring := parent___slots__ .get (props .name )):
234- docstring = tuple (prepare_docstring (docstring ))
235- return (docstring ,)
236- return ()
261+ return [prepare_docstring (docstring )]
262+ return []
237263 except ValueError as exc :
238264 logger .warning (
239265 __ ('Invalid __slots__ found on %s. Ignored.' ),
240266 (parent .__qualname__ , exc ),
241267 type = 'autodoc' ,
242268 )
243- return ()
269+ return []
244270
245271 if (
246272 obj is RUNTIME_INSTANCE_ATTRIBUTE
@@ -262,7 +288,6 @@ def _get_docstring_lines(
262288 obj ,
263289 props = props ,
264290 inherit_docstrings = inherit_docstrings ,
265- _new_docstrings = _new_docstrings ,
266291 parent = parent ,
267292 tab_width = tab_width ,
268293 )
@@ -271,7 +296,6 @@ def _get_docstring_lines(
271296 obj ,
272297 props = props ,
273298 inherit_docstrings = inherit_docstrings ,
274- _new_docstrings = _new_docstrings ,
275299 parent = parent ,
276300 tab_width = tab_width ,
277301 )
@@ -283,23 +307,16 @@ def _get_doc(
283307 * ,
284308 props : _ItemProperties ,
285309 inherit_docstrings : bool ,
286- _new_docstrings : Sequence [Sequence [str ]] | None ,
287310 parent : Any ,
288311 tab_width : int ,
289- ) -> Sequence [ Sequence [str ]] | None :
312+ ) -> list [ list [str ]] | None :
290313 """Decode and return lines of the docstring(s) for the object.
291314
292315 When it returns None, autodoc-process-docstring will not be called for this
293316 object.
294317 """
295318 if obj is UNINITIALIZED_ATTR :
296- return ()
297-
298- if props .obj_type not in {'module' , 'data' } and _new_docstrings is not None :
299- # docstring already returned previously, then modified due to
300- # ``_extract_signatures_from_docstring()``. Just return the
301- # previously-computed result, so that we don't lose the processing.
302- return _new_docstrings
319+ return []
303320
304321 docstring = getdoc (
305322 obj ,
@@ -308,8 +325,8 @@ def _get_doc(
308325 name = props .object_name ,
309326 )
310327 if docstring :
311- return ( tuple ( prepare_docstring (docstring , tab_width )),)
312- return ()
328+ return [ prepare_docstring (docstring , tab_width )]
329+ return []
313330
314331
315332def _class_variable_comment (props : _ItemProperties ) -> bool :
0 commit comments