Skip to content

Commit

Permalink
feat: Support in[tro]spection
Browse files Browse the repository at this point in the history
  • Loading branch information
pawamoy committed Nov 27, 2021
1 parent 31fcdb1 commit 3a0587d
Show file tree
Hide file tree
Showing 7 changed files with 747 additions and 24 deletions.
20 changes: 20 additions & 0 deletions src/griffe/agents/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,23 @@ def generic_visit(self, node: ast.AST) -> None: # noqa: WPS231
for child in node.children: # type: ignore[attr-defined] # noqa: WPS437
self.visit(child)


class BaseInspector:
"""The base class for inspectors."""

def inspect(self, node: ObjectNode) -> None:
"""Inspect a node.
Parameters:
node: The node to inspect.
"""
getattr(self, f"inspect_{node.kind}", self.generic_inspect)(node)

def generic_inspect(self, node: ObjectNode) -> None: # noqa: WPS231
"""Inspect the children of a node.
Parameters:
node: The node to inspect (its children).
"""
for child in node.children:
self.inspect(child)
84 changes: 80 additions & 4 deletions src/griffe/agents/extensions/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@
from types import ModuleType
from typing import TYPE_CHECKING, Any, Sequence, Type, Union

from griffe.agents.base import BaseVisitor
from griffe.agents.base import BaseInspector, BaseVisitor

if TYPE_CHECKING:
from griffe.agents.inspector import Inspector
from griffe.agents.visitor import Visitor


class When(enum.Enum):
"""This enumeration contains the different times at which an extension is used.
Expand Down Expand Up @@ -47,7 +50,26 @@ def attach(self, visitor: Visitor) -> None:
self.visitor = visitor


Extension = Union[VisitorExtension]
class InspectorExtension(BaseInspector):
"""The object inspector extension base class, to inherit from."""

when: When

def __init__(self) -> None:
"""Initialize the inspector extension."""
super().__init__()
self.inspector: Inspector = None # type: ignore[assignment]

def attach(self, inspector: Inspector) -> None:
"""Attach the parent inspector to this extension.
Parameters:
inspector: The parent inspector.
"""
self.inspector = inspector


Extension = Union[VisitorExtension, InspectorExtension]


class Extensions:
Expand All @@ -60,6 +82,7 @@ def __init__(self, *extensions: Extension) -> None:
*extensions: The extensions to add.
"""
self._visitors: dict[When, list[VisitorExtension]] = defaultdict(list)
self._inspectors: dict[When, list[InspectorExtension]] = defaultdict(list)
self.add(*extensions)

def add(self, *extensions: Extension) -> None:
Expand All @@ -71,6 +94,8 @@ def add(self, *extensions: Extension) -> None:
for extension in extensions:
if isinstance(extension, VisitorExtension):
self._visitors[extension.when].append(extension)
else:
self._inspectors[extension.when].append(extension)

def attach_visitor(self, parent_visitor: Visitor) -> Extensions:
"""Attach a parent visitor to the visitor extensions.
Expand All @@ -86,6 +111,20 @@ def attach_visitor(self, parent_visitor: Visitor) -> Extensions:
visitor.attach(parent_visitor)
return self

def attach_inspector(self, parent_inspector: Inspector) -> Extensions:
"""Attach a parent inspector to the inspector extensions.
Parameters:
parent_inspector: The parent inspector, leading the inspection.
Returns:
Self, conveniently.
"""
for when in self._inspectors.keys():
for inspector in self._inspectors[when]:
inspector.attach(parent_inspector)
return self

@property
def before_visit(self) -> list[VisitorExtension]:
"""Return the visitors that run before the visit.
Expand Down Expand Up @@ -122,6 +161,43 @@ def after_visit(self) -> list[VisitorExtension]:
"""
return self._visitors[When.after_all]

@property
def before_inspection(self) -> list[InspectorExtension]:
"""Return the inspectors that run before the inspection.
Returns:
Inspectors.
"""
return self._inspectors[When.before_all]

@property
def before_children_inspection(self) -> list[InspectorExtension]:
"""Return the inspectors that run before the children inspection.
Returns:
Inspectors.
"""
return self._inspectors[When.before_children]

@property
def after_children_inspection(self) -> list[InspectorExtension]:
"""Return the inspectors that run after the children inspection.
Returns:
Inspectors.
"""
return self._inspectors[When.after_children]

@property
def after_inspection(self) -> list[InspectorExtension]:
"""Return the inspectors that run after the inspection.
Returns:
Inspectors.
"""
return self._inspectors[When.after_all]


builtin_extensions: dict[str, ModuleType] = {}


Expand Down Expand Up @@ -155,10 +231,10 @@ def load_extensions(exts: Sequence[str | dict[str, Any] | Extension | Type[Exten
# TODO: handle AttributeError
extensions.add(ext_module.Extension(**options)) # type: ignore[attr-defined]

elif isinstance(extension, (VisitorExtension,)):
elif isinstance(extension, (VisitorExtension, InspectorExtension)):
extensions.add(extension)

elif isclass(extension) and issubclass(extension, (VisitorExtension,)):
elif isclass(extension) and issubclass(extension, (VisitorExtension, InspectorExtension)):
extensions.add(extension())

return extensions
Loading

0 comments on commit 3a0587d

Please sign in to comment.