Skip to content

Commit 4fc088f

Browse files
committed
Add and use HideReason enum
1 parent 3ac44d8 commit 4fc088f

File tree

2 files changed

+76
-60
lines changed

2 files changed

+76
-60
lines changed

autoapi/_mapper.py

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
PythonData,
3131
PythonException,
3232
_trace_visibility,
33+
HideReason,
3334
)
3435
from .settings import OWN_PAGE_LEVELS, TEMPLATE_DIR
3536

@@ -389,13 +390,6 @@ def _output_top_rst(self):
389390
# Render Top Index
390391
top_level_index = os.path.join(self.dir_root, "index.rst")
391392

392-
modules = [obj for obj in self.all_objects.values()
393-
if obj.type == "module" and obj.docstring == ""]
394-
if modules and "undoc-members" not in self.app.config.autoapi_options:
395-
_color_info("The following modules have no top-level documentation, and so were skipped as undocumented:")
396-
for m in modules:
397-
_color_info(f" {m.id}")
398-
399393
pages = [obj for obj in self.objects_to_render.values() if obj.display]
400394
if not pages:
401395
msg = (
@@ -508,7 +502,7 @@ def _skip_if_stdlib(self):
508502
and module not in documented_modules
509503
):
510504
_trace_visibility(self.app, f"Hiding {obj['qual_name']} as determined to be Python standard Library (found as {obj['full_name']})", verbose=2)
511-
obj["hide"] = True
505+
obj["hide_reasom"] = HideReason.STD_LIBRARY
512506

513507
def _resolve_placeholders(self):
514508
"""Resolve objects that have been imported from elsewhere."""
@@ -527,19 +521,18 @@ def _hide_yo_kids(self):
527521
for module in self.paths.values():
528522
if module["all"] is not None:
529523
all_names = set(module["all"])
530-
_trace_visibility(self.app, f"{module['full_name']}: Found __all__ =")
531524
for n in all_names:
532525
_trace_visibility(self.app, f" {n}")
533526
for child in module["children"]:
534527
if child["qual_name"] not in all_names:
535528
_trace_visibility(self.app, f"Hiding {child['full_name']}, as {child['qual_name']} not in __all__")
536-
child["hide"] = True
529+
child["hide_reason"] = HideReason.NOT_IN_ALL
537530
elif module["type"] == "module":
538531
_trace_visibility(self.app, f"Testing if any children of {module['full_name']} have already been documented")
539532
for child in module["children"]:
540533
if "original_path" in child:
541-
_trace_visibility(self.app, f"Hiding {child['full_name']} as documented at {child['original_path']}")
542-
child["hide"] = True
534+
_trace_visibility(self.app, f"Hiding {child['full_name']} as it appears to be in your public API at {child['original_path']}")
535+
child["hide_reason"] = HideReason.NOT_PUBLIC
543536

544537
def map(self, options=None):
545538
self._skip_if_stdlib()
@@ -583,17 +576,17 @@ def _render_selection(self):
583576
self.objects_to_render[obj.id] = obj
584577
else:
585578
if obj.subpackages or obj.submodules:
586-
_trace_visibility(self.app, f"Not rendering the following as {obj.id} set to not display:", verbose=2)
579+
_trace_visibility(self.app, f"Not rendering the following as {obj.id} set to not display because object is {obj.hide_reason}", verbose=2)
587580
for module in itertools.chain(obj.subpackages, obj.submodules):
588581
_trace_visibility(self.app, f" {module.obj['full_name']}", verbose=2)
589-
module.obj["hide"] = True
582+
module.obj["hide_reason"] = HideReason.PARENT_HIDDEN
590583

591584
def _inner(parent):
592585
for child in parent.children:
593586
self.all_objects[child.id] = child
594587
if not parent.display:
595588
_trace_visibility(self.app, f"Hiding {child.id} as parent {parent.id} will not be displayed", verbose=2)
596-
child.obj["hide"] = True
589+
child.obj["hide_reason"] = HideReason.PARENT_HIDDEN
597590

598591
if child.display and child.type in self.own_page_types:
599592
self.objects_to_render[child.id] = child
@@ -603,6 +596,15 @@ def _inner(parent):
603596
for obj in list(self.all_objects.values()):
604597
_inner(obj)
605598

599+
modules = [obj for obj in self.all_objects.values()
600+
if obj.type == "module" and obj.docstring == ""]
601+
if modules and "undoc-members" not in self.app.config.autoapi_options:
602+
_color_info("The following modules have no top-level documentation, and so were skipped as undocumented:")
603+
for m in modules:
604+
_color_info(f" {m.id}")
605+
606+
607+
606608
def create_class(self, data, options=None):
607609
"""Create a class from the passed in data
608610

autoapi/_objects.py

Lines changed: 59 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
import functools
44
import pathlib
55

6+
from enum import StrEnum, auto
7+
from typing import List
8+
69
import sphinx
710
import sphinx.util
811
import 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

3853
class 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

351365
class PythonProperty(PythonObject):
352366
"""The representation of a property on a class."""

0 commit comments

Comments
 (0)