5555import re
5656import sys
5757from inspect import Parameter
58- from pathlib import Path
5958from types import ModuleType
6059from typing import TYPE_CHECKING , cast
6160
6261from docutils import nodes
6362from docutils .parsers .rst import directives
64- from docutils .parsers .rst .states import RSTStateMachine , Struct , state_classes
63+ from docutils .parsers .rst .states import RSTStateMachine , state_classes
6564from docutils .statemachine import StringList
6665
6766import sphinx
6867from sphinx import addnodes
69- from sphinx .config import Config
70- from sphinx .environment import BuildEnvironment
7168from sphinx .errors import PycodeError
7269from sphinx .ext .autodoc ._directive_options import _AutoDocumenterOptions
7370from sphinx .ext .autodoc ._documenters import _best_object_type_for_member
7673from sphinx .ext .autodoc .importer import _format_signatures , import_module
7774from sphinx .ext .autodoc .mock import mock
7875from sphinx .locale import __
79- from sphinx .project import Project
8076from sphinx .pycode import ModuleAnalyzer
81- from sphinx .registry import SphinxComponentRegistry
8277from sphinx .util import logging , rst
8378from sphinx .util .docutils import (
8479 NullReporter ,
9893 from docutils .nodes import Node , system_message
9994
10095 from sphinx .application import Sphinx
96+ from sphinx .environment import BuildEnvironment
10197 from sphinx .ext .autodoc import Documenter
102- from sphinx .extension import Extension
98+ from sphinx .registry import SphinxComponentRegistry
10399 from sphinx .util .typing import ExtensionMetadata , OptionSpec
104100 from sphinx .writers .html5 import HTML5Translator
105101
@@ -158,31 +154,6 @@ def autosummary_table_visit_html(
158154# -- autodoc integration -------------------------------------------------------
159155
160156
161- class FakeApplication :
162- verbosity = 0
163-
164- def __init__ (self ) -> None :
165- self .doctreedir = Path ()
166- self .events = None
167- self .extensions : dict [str , Extension ] = {}
168- self .srcdir = Path ()
169- self .config = Config ()
170- self .project = Project ('' , {})
171- self .registry = SphinxComponentRegistry ()
172-
173-
174- class FakeDirective (DocumenterBridge ):
175- def __init__ (self ) -> None :
176- settings = Struct (tab_width = 8 )
177- document = Struct (settings = settings )
178- app = FakeApplication ()
179- app .config .add ('autodoc_class_signature' , 'mixed' , 'env' , ())
180- env = BuildEnvironment (app ) # type: ignore[arg-type]
181- opts = _AutoDocumenterOptions ()
182- state = Struct (document = document )
183- super ().__init__ (env , None , opts , 0 , state )
184-
185-
186157def get_documenter (app : Sphinx , obj : Any , parent : Any ) -> type [Documenter ]:
187158 """Get an autodoc.Documenter class suitable for documenting the given
188159 object.
@@ -191,43 +162,36 @@ def get_documenter(app: Sphinx, obj: Any, parent: Any) -> type[Documenter]:
191162 another Python object (e.g. a module or a class) to which *obj*
192163 belongs to.
193164 """
194- return _get_documenter (obj , parent , registry = app .registry )
165+ obj_type = _get_documenter (obj , parent )
166+ return app .registry .documenters [obj_type ]
195167
196168
197- def _get_documenter (
198- obj : Any , parent : Any , * , registry : SphinxComponentRegistry
199- ) -> type [Documenter ]:
169+ def _get_documenter (obj : Any , parent : Any ) -> str :
200170 """Get an autodoc.Documenter class suitable for documenting the given
201171 object.
202172
203173 *obj* is the Python object to be documented, and *parent* is an
204174 another Python object (e.g. a module or a class) to which *obj*
205175 belongs to.
206176 """
207- from sphinx .ext .autodoc import DataDocumenter , ModuleDocumenter
208-
209177 if inspect .ismodule (obj ):
210- return ModuleDocumenter
211-
212- # Construct a fake documenter for *parent*
213- if parent is not None :
214- parent_doc_cls = _get_documenter (parent , None , registry = registry )
215- else :
216- parent_doc_cls = ModuleDocumenter
178+ return 'module'
217179
218- if hasattr ( parent , '__name__' ) :
219- parent_doc = parent_doc_cls ( FakeDirective (), parent . __name__ )
180+ if parent is None :
181+ parent_obj_type = 'module'
220182 else :
221- parent_doc = parent_doc_cls ( FakeDirective (), '' )
183+ parent_obj_type = _get_documenter ( parent , None )
222184
223185 # Get the correct documenter class for *obj*
224- obj_type = _best_object_type_for_member (
225- member = obj , member_name = '' , is_attr = False , parent_documenter = parent_doc
226- )
227- if obj_type :
228- return registry .documenters [obj_type ]
229- else :
230- return DataDocumenter
186+ if obj_type := _best_object_type_for_member (
187+ member = obj ,
188+ member_name = '' ,
189+ is_attr = False ,
190+ parent_obj_type = parent_obj_type ,
191+ parent_props = None ,
192+ ):
193+ return obj_type
194+ return 'data'
231195
232196
233197# -- .. autosummary:: ----------------------------------------------------------
@@ -343,7 +307,8 @@ def create_documenter(
343307
344308 Wraps _get_documenter and is meant as a hook for extensions.
345309 """
346- doccls = _get_documenter (obj , parent , registry = registry )
310+ obj_type = _get_documenter (obj , parent )
311+ doccls = registry .documenters [obj_type ]
347312 return doccls (self .bridge , full_name )
348313
349314 def get_items (self , names : list [str ]) -> list [tuple [str , str | None , str , str ]]:
@@ -389,16 +354,16 @@ def get_items(self, names: list[str]) -> list[tuple[str, str | None, str, str]]:
389354 continue
390355
391356 self .bridge .result = StringList () # initialize for each documenter
357+ obj_type = _get_documenter (obj , parent )
358+ doccls = self .env ._registry .documenters [obj_type ]
392359 full_name = real_name
393360 if not isinstance (obj , ModuleType ):
394361 # give explicitly separated module name, so that members
395362 # of inner classes can be documented
396363 full_name = modname + '::' + full_name [len (modname ) + 1 :]
397364 # NB. using full_name here is important, since Documenters
398365 # handle module prefixes slightly differently
399- documenter = self .create_documenter (
400- obj , parent , full_name , registry = self .env ._registry
401- )
366+ documenter = doccls (self .bridge , full_name )
402367 if documenter ._load_object_by_name () is None :
403368 logger .warning (
404369 __ ('failed to import object %s' ),
0 commit comments