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 } { 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 } cache " , verbose = 2 )
264+             _trace_visibility (self .app , f"Skipping { self .id } { 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 } { 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 }  
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