77import sphinx .util
88import sphinx .util .logging
99
10+ from sphinx .util .console import colorize
11+
1012from .settings import OWN_PAGE_LEVELS
1113
1214LOGGER = sphinx .util .logging .getLogger (__name__ )
1315
16+ def _trace_visibility (app , msg : str , verbose = 1 ) -> None :
17+ if app .config .autoapi_verbose_visibility >= verbose :
18+ LOGGER .info (colorize ("bold" , f"[AutoAPI] [Visibility] { msg } " ))
19+
1420
1521def _format_args (args_info , include_annotations = True , ignore_self = None ):
1622 result = []
@@ -79,6 +85,7 @@ def __init__(
7985 # For later
8086 self ._class_content = class_content
8187 self ._display_cache : bool | None = None
88+ self ._skip_reason = None
8289
8390 def __getstate__ (self ):
8491 """Obtains serialisable data for pickling."""
@@ -199,8 +206,13 @@ def display(self) -> bool:
199206 This attribute depends on the configuration options given in
200207 :confval:`autoapi_options` and the result of :event:`autoapi-skip-member`.
201208 """
209+ skip = self ._should_skip ()
202210 if self ._display_cache is None :
203- self ._display_cache = not self ._ask_ignore (self ._should_skip ())
211+ self ._display_cache = not self ._ask_ignore (skip )
212+ if self ._display_cache is False :
213+ _trace_visibility (self .app , self ._skip_reason )
214+ else :
215+ _trace_visibility (self .app , f"Skipping { self .id } due to cache" , verbose = 2 )
204216
205217 return self ._display_cache
206218
@@ -231,6 +243,22 @@ def _should_skip(self) -> bool:
231243 self .inherited and "inherited-members" not in self .options
232244 )
233245
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+
234262 return (
235263 self .obj .get ("hide" , False )
236264 or skip_undoc_member
@@ -241,10 +269,16 @@ def _should_skip(self) -> bool:
241269 )
242270
243271 def _ask_ignore (self , skip : bool ) -> bool :
272+
244273 ask_result = self .app .emit_firstresult (
245274 "autoapi-skip-member" , self .type , self .id , self , skip , self .options
246275 )
247276
277+ if ask_result is not None :
278+ reason = f"Skipping as 'autoapi-skip-member' returned { ask_result } "
279+ if self ._skip_reason :
280+ reason += f"Passed skip={ skip } to 'autoapi-skip-member' as { self ._skip_reason } "
281+ self ._skip_reason = reason
248282 return ask_result if ask_result is not None else skip
249283
250284 def _children_of_type (self , type_ : str ) -> list [PythonObject ]:
@@ -306,11 +340,13 @@ def __init__(self, *args, **kwargs):
306340 """
307341
308342 def _should_skip (self ) -> bool :
309- return super (). _should_skip () or self .name in (
343+ is_new_or_init = self .name in (
310344 "__new__" ,
311345 "__init__" ,
312346 )
313-
347+ if not super ()._should_skip and is_new_or_init :
348+ self ._skip_reason = f"Skipping method { self .id } as is __new__ or __init__"
349+ return super ()._should_skip () or is_new_or_init
314350
315351class PythonProperty (PythonObject ):
316352 """The representation of a property on a class."""
0 commit comments