Skip to content

Commit

Permalink
refactor: Clean up and document internal API, mark legacy code
Browse files Browse the repository at this point in the history
  • Loading branch information
pawamoy committed Jul 14, 2024
1 parent ddc5b0c commit 92594a9
Show file tree
Hide file tree
Showing 42 changed files with 810 additions and 941 deletions.
35 changes: 0 additions & 35 deletions src/_griffe/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,3 @@
Extract the structure, the frame, the skeleton of your project,
to generate API documentation or find breaking changes in your API.
"""

from __future__ import annotations

from griffe.agents.nodes import ObjectNode
from griffe.models import Attribute, Class, Docstring, Function, Module, Object
from griffe.diff import find_breaking_changes
from griffe.docstrings.google import parse as parse_google
from griffe.docstrings.numpy import parse as parse_numpy
from griffe.docstrings.sphinx import parse as parse_sphinx
from griffe.enumerations import Parser
from griffe.extensions.base import Extension, load_extensions
from griffe.importer import dynamic_import
from griffe.loader import load, load_git
from griffe.logger import get_logger

__all__: list[str] = [
"Attribute",
"Class",
"Docstring",
"dynamic_import",
"Extension",
"Function",
"find_breaking_changes",
"get_logger",
"load",
"load_extensions",
"load_git",
"Module",
"Object",
"ObjectNode",
"Parser",
"parse_google",
"parse_numpy",
"parse_sphinx",
]
58 changes: 37 additions & 21 deletions src/_griffe/agents/inspector.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
we always try to visit the code first, and only then we load the object
to update the data with introspection.
This module exposes a public function, [`inspect()`][griffe.agents.inspector.inspect],
This module exposes a public function, [`inspect()`][griffe.inspect],
which inspects the module using [`inspect.getmembers()`][inspect.getmembers],
and returns a new [`Module`][griffe.models.Module] instance,
and returns a new [`Module`][griffe.Module] instance,
populating its members recursively, by using a [`NodeVisitor`][ast.NodeVisitor]-like class.
The inspection agent works similarly to the regular "node visitor" agent,
Expand All @@ -28,24 +28,25 @@
from inspect import signature as getsignature
from typing import TYPE_CHECKING, Any, Sequence

from griffe.agents.nodes import ObjectNode
from griffe.collections import LinesCollection, ModulesCollection
from griffe.models import Alias, Attribute, Class, Docstring, Function, Module, Parameter, Parameters
from griffe.enumerations import ObjectKind, ParameterKind
from griffe.expressions import safe_get_annotation
from griffe.extensions.base import Extensions, load_extensions
from griffe.importer import dynamic_import
from griffe.logger import get_logger
from _griffe.agents.nodes.runtime import ObjectNode
from _griffe.collections import LinesCollection, ModulesCollection
from _griffe.enumerations import ObjectKind, ParameterKind
from _griffe.expressions import safe_get_annotation
from _griffe.extensions.base import Extensions, load_extensions
from _griffe.importer import dynamic_import
from _griffe.logger import get_logger
from _griffe.models import Alias, Attribute, Class, Docstring, Function, Module, Parameter, Parameters

if TYPE_CHECKING:
from pathlib import Path

from griffe.enumerations import Parser
from griffe.expressions import Expr
from _griffe.enumerations import Parser
from _griffe.expressions import Expr


logger = get_logger(__name__)
empty = Signature.empty
# YORE: Bump 1.0.0: Regex-replace `\.[^"]+` with `` within line.
_logger = get_logger("griffe.agents.inspector")
_empty = Signature.empty


def inspect(
Expand Down Expand Up @@ -118,15 +119,33 @@ def __init__(
modules_collection: A collection of modules.
"""
super().__init__()

self.module_name: str = module_name
"""The module name."""

self.filepath: Path | None = filepath
"""The module file path."""

self.extensions: Extensions = extensions.attach_inspector(self)
"""The extensions to use when inspecting."""

self.parent: Module | None = parent
"""An optional parent for the final module object."""

self.current: Module | Class = None # type: ignore[assignment]
"""The current object being inspected."""

self.docstring_parser: Parser | None = docstring_parser
"""The docstring parser to use."""

self.docstring_options: dict[str, Any] = docstring_options or {}
"""The docstring parsing options."""

self.lines_collection: LinesCollection = lines_collection or LinesCollection()
"""A collection of source code lines."""

self.modules_collection: ModulesCollection = modules_collection or ModulesCollection()
"""A collection of modules."""

def _get_docstring(self, node: ObjectNode) -> Docstring | None:
try:
Expand Down Expand Up @@ -239,7 +258,7 @@ def generic_inspect(self, node: ObjectNode) -> None:
# so we skip it here (no member, no alias, just skip it).
if child.is_module and target_path == f"{self.current.path}.{child.name}":
if not hasattr(child.obj, "__file__"):
logger.debug(f"Module {target_path} is not discoverable on disk, inspecting right now")
_logger.debug(f"Module {target_path} is not discoverable on disk, inspecting right now")
inspector = Inspector(
child.name,
filepath=None,
Expand Down Expand Up @@ -422,7 +441,7 @@ def handle_function(self, node: ObjectNode, labels: set | None = None) -> None:
return_annotation = signature.return_annotation
returns = (
None
if return_annotation is empty
if return_annotation is _empty
else _convert_object_to_annotation(return_annotation, parent=self.current)
)

Expand Down Expand Up @@ -524,10 +543,10 @@ def handle_attribute(self, node: ObjectNode, annotation: str | Expr | None = Non
def _convert_parameter(parameter: SignatureParameter, parent: Module | Class) -> Parameter:
name = parameter.name
annotation = (
None if parameter.annotation is empty else _convert_object_to_annotation(parameter.annotation, parent=parent)
None if parameter.annotation is _empty else _convert_object_to_annotation(parameter.annotation, parent=parent)
)
kind = _kind_map[parameter.kind]
if parameter.default is empty:
if parameter.default is _empty:
default = None
elif hasattr(parameter.default, "__name__"):
# avoid repr containing chevrons and memory addresses
Expand Down Expand Up @@ -555,6 +574,3 @@ def _convert_object_to_annotation(obj: Any, parent: Module | Class) -> str | Exp
except SyntaxError:
return obj
return safe_get_annotation(annotation_node.body, parent=parent) # type: ignore[attr-defined]


__all__ = ["inspect", "Inspector"]
81 changes: 0 additions & 81 deletions src/_griffe/agents/nodes/__init__.py
Original file line number Diff line number Diff line change
@@ -1,82 +1 @@
"""This module contains utilities for extracting information from nodes."""

from __future__ import annotations

import warnings
from typing import Any

from griffe.agents.nodes._all import get__all__, safe_get__all__
from griffe.agents.nodes._ast import (
ast_children,
ast_first_child,
ast_kind,
ast_last_child,
ast_next,
ast_next_siblings,
ast_previous,
ast_previous_siblings,
ast_siblings,
)
from griffe.agents.nodes._docstrings import get_docstring
from griffe.agents.nodes._imports import relative_to_absolute
from griffe.agents.nodes._names import get_instance_names, get_name, get_names
from griffe.agents.nodes._parameters import get_parameters
from griffe.agents.nodes._runtime import ObjectNode
from griffe.agents.nodes._values import get_value, safe_get_value
from griffe.enumerations import ObjectKind


def __getattr__(name: str) -> Any:
if name in {
"get_annotation",
"get_base_class",
"get_condition",
"get_expression",
"safe_get_annotation",
"safe_get_base_class",
"safe_get_condition",
"safe_get_expression",
}:
warnings.warn(
f"Importing {name} from griffe.agents.node is deprecated. Import it from griffe.expressions instead.",
DeprecationWarning,
stacklevel=2,
)

from griffe import expressions

return getattr(expressions, name)
raise AttributeError


__all__ = [
"ast_children",
"ast_first_child",
"ast_kind",
"ast_last_child",
"ast_next",
"ast_next_siblings",
"ast_previous",
"ast_previous_siblings",
"ast_siblings",
"get__all__",
"get_annotation",
"get_base_class",
"get_condition",
"get_docstring",
"get_expression",
"get_instance_names",
"get_name",
"get_names",
"get_parameters",
"get_value",
"ObjectKind",
"ObjectNode",
"relative_to_absolute",
"safe_get__all__",
"safe_get_annotation",
"safe_get_base_class",
"safe_get_condition",
"safe_get_expression",
"safe_get_value",
]
8 changes: 3 additions & 5 deletions src/_griffe/agents/nodes/assignments.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
import ast
from typing import Any, Callable

from griffe.logger import get_logger
from _griffe.logger import get_logger

logger = get_logger(__name__)
# YORE: Bump 1.0.0: Regex-replace `\.[^"]+` with `` within line.
_logger = get_logger("griffe.agents.nodes._names")


def _get_attribute_name(node: ast.Attribute) -> str:
Expand Down Expand Up @@ -74,6 +75,3 @@ def get_instance_names(node: ast.AST) -> list[str]:
A list of names.
"""
return [name.split(".", 1)[1] for name in get_names(node) if name.startswith("self.")]


__all__ = ["get_instance_names", "get_name", "get_names"]
20 changes: 4 additions & 16 deletions src/_griffe/agents/nodes/ast.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
from ast import AST
from typing import Iterator

from griffe.exceptions import LastNodeError
from griffe.logger import get_logger
from _griffe.exceptions import LastNodeError
from _griffe.logger import get_logger

logger = get_logger(__name__)
# YORE: Bump 1.0.0: Regex-replace `\.[^"]+` with `` within line.
_logger = get_logger("griffe.agents.nodes._ast")


def ast_kind(node: AST) -> str:
Expand Down Expand Up @@ -169,16 +170,3 @@ def ast_last_child(node: AST) -> AST:
except ValueError as error:
raise LastNodeError("there are no children node") from error
return last


__all__ = [
"ast_children",
"ast_first_child",
"ast_kind",
"ast_last_child",
"ast_next",
"ast_next_siblings",
"ast_previous",
"ast_previous_siblings",
"ast_siblings",
]
8 changes: 3 additions & 5 deletions src/_griffe/agents/nodes/docstrings.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@

import ast

from griffe.logger import get_logger
from _griffe.logger import get_logger

logger = get_logger(__name__)
# YORE: Bump 1.0.0: Regex-replace `\.[^"]+` with `` within line.
_logger = get_logger("griffe.agents.nodes._docstrings")


def get_docstring(
Expand All @@ -33,6 +34,3 @@ def get_docstring(
if isinstance(doc, ast.Constant) and isinstance(doc.value, str):
return doc.value, doc.lineno, doc.end_lineno
return None, None, None


__all__ = ["get_docstring"]
Loading

0 comments on commit 92594a9

Please sign in to comment.