Skip to content

Commit 6e1993d

Browse files
committed
Add initial try at user level debugging for object visibility
1 parent 26bd172 commit 6e1993d

File tree

3 files changed

+52
-3
lines changed

3 files changed

+52
-3
lines changed

autoapi/_mapper.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
PythonAttribute,
3030
PythonData,
3131
PythonException,
32+
_trace_visibility,
3233
)
3334
from .settings import OWN_PAGE_LEVELS, TEMPLATE_DIR
3435

@@ -499,6 +500,7 @@ def _skip_if_stdlib(self):
499500
and not obj["inherited_from"]["is_abstract"]
500501
and module not in documented_modules
501502
):
503+
_trace_visibility(self.app, f"Hiding {obj['qual_name']} as determined to be Python standard Library (found as {obj['full_name']})", verbose=2)
502504
obj["hide"] = True
503505

504506
def _resolve_placeholders(self):
@@ -518,12 +520,18 @@ def _hide_yo_kids(self):
518520
for module in self.paths.values():
519521
if module["all"] is not None:
520522
all_names = set(module["all"])
523+
_trace_visibility(self.app, f"{module['full_name']}: Found __all__ =")
524+
for n in all_names:
525+
_trace_visibility(self.app, f" {n}")
521526
for child in module["children"]:
522527
if child["qual_name"] not in all_names:
528+
_trace_visibility(self.app, f"Hiding {child['full_name']}, as {child['qual_name']} not in __all__")
523529
child["hide"] = True
524530
elif module["type"] == "module":
531+
_trace_visibility(self.app, f"Testing if any children of {module['full_name']} have already been documented")
525532
for child in module["children"]:
526533
if "original_path" in child:
534+
_trace_visibility(self.app, f"Hiding {child['full_name']} as documented at {child['original_path']}")
527535
child["hide"] = True
528536

529537
def map(self, options=None):
@@ -567,13 +575,17 @@ def _render_selection(self):
567575
assert obj.type in self.own_page_types
568576
self.objects_to_render[obj.id] = obj
569577
else:
578+
if obj.subpackages or obj.submodules:
579+
_trace_visibility(self.app, f"Not rendering the following as {obj.id} set to not display:", verbose=2)
570580
for module in itertools.chain(obj.subpackages, obj.submodules):
581+
_trace_visibility(self.app, f" {module.obj['full_name']}", verbose=2)
571582
module.obj["hide"] = True
572583

573584
def _inner(parent):
574585
for child in parent.children:
575586
self.all_objects[child.id] = child
576587
if not parent.display:
588+
_trace_visibility(self.app, f"Hiding {child.id} as parent {parent.id} will not be displayed", verbose=2)
577589
child.obj["hide"] = True
578590

579591
if child.display and child.type in self.own_page_types:

autoapi/_objects.py

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,16 @@
77
import sphinx.util
88
import sphinx.util.logging
99

10+
from sphinx.util.console import colorize
11+
1012
from .settings import OWN_PAGE_LEVELS
1113

1214
LOGGER = 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

1521
def _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

315351
class PythonProperty(PythonObject):
316352
"""The representation of a property on a class."""

autoapi/extension.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ def setup(app):
261261
app.add_config_value("autoapi_generate_api_docs", True, "html")
262262
app.add_config_value("autoapi_prepare_jinja_env", None, "html")
263263
app.add_config_value("autoapi_own_page_level", "module", "html")
264+
app.add_config_value("autoapi_verbose_visibility", 0, "html")
264265
app.add_autodocumenter(documenters.AutoapiFunctionDocumenter)
265266
app.add_autodocumenter(documenters.AutoapiPropertyDocumenter)
266267
app.add_autodocumenter(documenters.AutoapiDecoratorDocumenter)

0 commit comments

Comments
 (0)