3030if TYPE_CHECKING :
3131 from collections .abc import Iterator
3232 from types import ModuleType
33- from typing import Any , ClassVar , Literal
33+ from typing import Any , ClassVar , Final , Literal
3434
3535 from sphinx .config import Config
3636 from sphinx .environment import BuildEnvironment , _CurrentDocument
@@ -79,8 +79,6 @@ class Documenter:
7979 #: name by which the directive is called (auto...) and the default
8080 #: generated directive name
8181 objtype : ClassVar = 'object'
82- #: indentation by which to indent the directive content
83- content_indent : ClassVar = ' '
8482 #: order if autodoc_member_order is set to 'groupwise'
8583 member_order : ClassVar = 0
8684 #: true if the generated content may contain titles
@@ -109,7 +107,7 @@ def __init__(
109107 self ._events : EventManager = directive .env .events
110108 self .options : _AutoDocumenterOptions = directive .genopt
111109 self .name = name
112- self .indent = indent
110+ self .indent : Final = indent
113111 # the module and object path within the module, and the fully
114112 # qualified name (all set after resolve_name succeeds)
115113 self .modname : str = ''
@@ -141,10 +139,10 @@ def documenters(self) -> dict[str, type[Documenter]]:
141139 """Returns registered Documenter classes"""
142140 return self .env ._registry .documenters
143141
144- def add_line (self , line : str , source : str , * lineno : int ) -> None :
142+ def add_line (self , line : str , source : str , * lineno : int , indent : str ) -> None :
145143 """Append one line of generated reST to the output."""
146144 if line .strip (): # not a blank line
147- self .directive .result .append (self . indent + line , source , * lineno )
145+ self .directive .result .append (indent + line , source , * lineno )
148146 else :
149147 self .directive .result .append ('' , source , * lineno )
150148
@@ -278,7 +276,7 @@ def _call_format_args(self, **kwargs: Any) -> str:
278276 # retry without arguments for old documenters
279277 return self .format_args ()
280278
281- def add_directive_header (self ) -> None :
279+ def add_directive_header (self , * , indent : str ) -> None :
282280 """Add the directive header and options to the generated content."""
283281 domain_name = getattr (self , 'domain' , 'py' )
284282 if self .objtype in {'class' , 'exception' } and self .props .doc_as_attr : # type: ignore[attr-defined]
@@ -292,7 +290,6 @@ def add_directive_header(self) -> None:
292290 else :
293291 is_final = False
294292
295- indent = self .indent
296293 result = self .directive .result
297294 sourcename = self .get_sourcename ()
298295 for line in _directive_header_lines (
@@ -322,7 +319,7 @@ def get_sourcename(self) -> str:
322319 else :
323320 return 'docstring of %s' % fullname
324321
325- def add_content (self , more_content : StringList | None ) -> None :
322+ def add_content (self , more_content : StringList | None , * , indent : str ) -> None :
326323 """Add content from docstrings, attribute documentation and user."""
327324 # add content from docstrings
328325 processed_doc = StringList (
@@ -340,7 +337,7 @@ def add_content(self, more_content: StringList | None) -> None:
340337 _add_content (
341338 processed_doc ,
342339 result = self .directive .result ,
343- indent = self . indent + ' ' * ( self . props . obj_type == 'module' ) ,
340+ indent = indent + ' ' ,
344341 )
345342
346343 # add additional content (e.g. from document), if present
@@ -353,7 +350,7 @@ def add_content(self, more_content: StringList | None) -> None:
353350 _add_content (
354351 more_content ,
355352 result = self .directive .result ,
356- indent = self .indent ,
353+ indent = indent + ' ' * ( self .props . obj_type != 'module' ) ,
357354 )
358355
359356 def _get_docstrings (self ) -> list [list [str ]] | None :
@@ -569,10 +566,6 @@ def _generate(
569566 check_module : bool = False ,
570567 all_members : bool = False ,
571568 ) -> None :
572- has_members = isinstance (self , ModuleDocumenter ) or (
573- isinstance (self , ClassDocumenter ) and not self .props .doc_as_attr
574- )
575-
576569 # If there is no real module defined, figure out which to use.
577570 # The real module is used in the module analyzer to look up the module
578571 # where the attribute documentation would actually be found in.
@@ -597,14 +590,6 @@ def _generate(
597590 else :
598591 self .directive .record_dependencies .add (self .analyzer .srcname )
599592
600- want_all = bool (
601- all_members or self .options .inherited_members or self .options .members is ALL
602- )
603- if has_members :
604- member_documenters = self ._gather_members (
605- want_all = want_all , indent = self .indent + self .content_indent
606- )
607-
608593 if self .real_modname != guess_modname :
609594 # Add module to dependency list if target object is defined in other module.
610595 try :
@@ -629,25 +614,32 @@ def _generate(
629614 if modname and modname != self .props .module_name :
630615 return
631616
617+ indent = self .indent
632618 sourcename = self .get_sourcename ()
633619
634620 # make sure that the result starts with an empty line. This is
635621 # necessary for some situations where another directive preprocesses
636622 # reST and no starting newline is present
637- self .add_line ('' , sourcename )
623+ self .directive . result . append ('' , sourcename )
638624
639625 # generate the directive header and options, if applicable
640- self .add_directive_header ()
641- self .add_line ('' , sourcename )
642-
643- # e.g. the module directive doesn't have content
644- self .indent += self .content_indent
626+ self .add_directive_header (indent = indent )
627+ self .directive .result .append ('' , sourcename )
645628
646629 # add all content (from docstrings, attribute docs etc.)
647- self .add_content (more_content )
630+ self .add_content (more_content , indent = indent )
648631
649632 # document members, if possible
633+ has_members = isinstance (self , ModuleDocumenter ) or (
634+ isinstance (self , ClassDocumenter ) and not self .props .doc_as_attr
635+ )
650636 if has_members :
637+ want_all = bool (
638+ all_members
639+ or self .options .inherited_members
640+ or self .options .members is ALL
641+ )
642+ member_documenters = self ._gather_members (want_all = want_all , indent = indent )
651643 # for implicit module members, check __module__ to avoid
652644 # documenting imported objects
653645 members_check_module = bool (
@@ -677,6 +669,7 @@ def _gather_members(
677669 events = self ._events
678670 registry = self .env ._registry
679671 props = self .props
672+ indent += ' ' * (props .obj_type != 'module' )
680673
681674 # set current namespace for finding members
682675 current_document .autodoc_module = props .module_name
@@ -759,8 +752,6 @@ class ModuleDocumenter(Documenter):
759752 props : _ModuleProperties
760753
761754 objtype = 'module'
762- content_indent = ''
763- _extra_indent = ' '
764755
765756 option_spec : ClassVar [OptionSpec ] = {
766757 'members' : members_option ,
0 commit comments