33import functools
44import pathlib
55
6+ from enum import StrEnum , auto
7+ from typing import List
8+
69import sphinx
710import sphinx .util
811import sphinx .util .logging
@@ -34,6 +37,18 @@ def _format_args(args_info, include_annotations=True, ignore_self=None):
3437
3538 return ", " .join (result )
3639
40+ class HideReason (StrEnum ):
41+ NOT_HIDDEN = "not hidden"
42+ UNDOC_MEMBER = "undocumented"
43+ PRIVATE_MEMBER = "a private member"
44+ SPECIAL_MEMBER = "a special member"
45+ IMPORTED_MEMBER = "an imported member"
46+ INHERITED_MEMBER = "an inherited member"
47+ IS_NEW_OR_INIT = "__new__ or __init__"
48+ NOT_IN_ALL = "not in __all__ for module"
49+ PARENT_HIDDEN = "parent is hidden"
50+ STD_LIBRARY = "part of Python standard library"
51+
3752
3853class PythonObject :
3954 """A class representing an entity from the parsed source code.
@@ -50,7 +65,7 @@ class PythonObject:
5065 type : str
5166
5267 def __init__ (
53- self , obj , jinja_env , app , url_root , options = None , class_content = "class"
68+ self , obj , jinja_env , app , url_root , options : List [ str ] = [] , class_content = "class"
5469 ):
5570 self .app = app
5671 self .obj = obj
@@ -85,7 +100,7 @@ def __init__(
85100 # For later
86101 self ._class_content = class_content
87102 self ._display_cache : bool | None = None
88- self ._skip_reason = None
103+ self ._skip_reason = ""
89104
90105 def __getstate__ (self ):
91106 """Obtains serialisable data for pickling."""
@@ -199,20 +214,54 @@ def is_special_member(self) -> bool:
199214 """Whether this object is a special member (True) or not (False)."""
200215 return self .short_name .startswith ("__" ) and self .short_name .endswith ("__" )
201216
217+ @property
218+ def hide_reason (self ) -> HideReason :
219+ skip_undoc_member = self .is_undoc_member and "undoc-members" not in self .options
220+ skip_private_member = (
221+ self .is_private_member and "private-members" not in self .options
222+ )
223+ skip_special_member = (
224+ self .is_special_member and "special-members" not in self .options
225+ )
226+ skip_imported_member = self .imported and "imported-members" not in self .options
227+ skip_inherited_member = (
228+ self .inherited and "inherited-members" not in self .options
229+ )
230+
231+ reason = HideReason .NOT_HIDDEN
232+ if self .obj .get ("hide" , False ):
233+ reason = HideReason .MARKED_HIDDEN
234+ elif skip_undoc_member :
235+ reason = HideReason .UNDOC_MEMBER
236+ elif skip_private_member :
237+ reason = HideReason .UNDOC_MEMBER
238+ elif skip_special_member :
239+ reason = HideReason .SPECIAL_MEMBER
240+ elif skip_imported_member :
241+ reason = HideReason .IMPORTED_MEMBER
242+ elif skip_inherited_member :
243+ reason = HideReason .INHERITED_MEMBER
244+
245+ self ._skip_reason = f"Skipping { self .id } as object is { reason } "
246+
247+ return reason
248+
249+
202250 @property
203251 def display (self ) -> bool :
204252 """Whether this object should be displayed in documentation.
205253
206254 This attribute depends on the configuration options given in
207255 :confval:`autoapi_options` and the result of :event:`autoapi-skip-member`.
208256 """
209- skip = self ._should_skip ()
257+ skip = self .hide_reason != HideReason .NOT_HIDDEN
258+
210259 if self ._display_cache is None :
211260 self ._display_cache = not self ._ask_ignore (skip )
212261 if self ._display_cache is False :
213262 _trace_visibility (self .app , self ._skip_reason )
214263 else :
215- _trace_visibility (self .app , f"Skipping { self .id } due to cache " , verbose = 2 )
264+ _trace_visibility (self .app , f"Skipping { self .id } due to { self . hide_reason } " , verbose = 2 )
216265
217266 return self ._display_cache
218267
@@ -230,44 +279,6 @@ def summary(self) -> str:
230279
231280 return ""
232281
233- def _should_skip (self ) -> bool :
234- skip_undoc_member = self .is_undoc_member and "undoc-members" not in self .options
235- skip_private_member = (
236- self .is_private_member and "private-members" not in self .options
237- )
238- skip_special_member = (
239- self .is_special_member and "special-members" not in self .options
240- )
241- skip_imported_member = self .imported and "imported-members" not in self .options
242- skip_inherited_member = (
243- self .inherited and "inherited-members" not in self .options
244- )
245-
246- reason = ""
247- if self .obj .get ("hide" , False ):
248- reason = "marked hidden by mapper"
249- elif skip_undoc_member :
250- reason = "is undocumented"
251- elif skip_private_member :
252- reason = "is a private member"
253- elif skip_special_member :
254- reason = "is a special member"
255- elif skip_imported_member :
256- reason = "is an imported member"
257- elif skip_inherited_member :
258- reason = "is an inherited member"
259-
260- self ._skip_reason = f"Skipping { self .id } as { reason } "
261-
262- return (
263- self .obj .get ("hide" , False )
264- or skip_undoc_member
265- or skip_private_member
266- or skip_special_member
267- or skip_imported_member
268- or skip_inherited_member
269- )
270-
271282 def _ask_ignore (self , skip : bool ) -> bool :
272283
273284 ask_result = self .app .emit_firstresult (
@@ -339,14 +350,17 @@ def __init__(self, *args, **kwargs):
339350 Can be any of: abstractmethod, async, classmethod, property, staticmethod.
340351 """
341352
342- def _should_skip (self ) -> bool :
353+ @property
354+ def hide_reason (self ) -> HideReason :
343355 is_new_or_init = self .name in (
344356 "__new__" ,
345357 "__init__" ,
346358 )
347- if not super ()._should_skip and is_new_or_init :
359+ hide_reason = super ().hide_reason
360+ if hide_reason != HideReason .NOT_HIDDEN and is_new_or_init :
348361 self ._skip_reason = f"Skipping method { self .id } as is __new__ or __init__"
349- return super ()._should_skip () or is_new_or_init
362+ return HideReason .IS_NEW_OR_INIT
363+ return hide_reason
350364
351365class PythonProperty (PythonObject ):
352366 """The representation of a property on a class."""
0 commit comments