Skip to content

Commit

Permalink
refactor: Improve expressions
Browse files Browse the repository at this point in the history
Expressions are now proper objects,
not just recursive lists of strings and names.
This increases robustness for checking if
an expression is a tuple, an iterator, etc.,
and when getting the n-th item of tuples, etc.

This will also make it easier to write
powerful and robust Griffe extensions.

Breaking changes:
- `griffe.expressions.Name` was removed
- `griffe.expressions.Expression` was removed
- mkdocstrings-python 1.2.1 templates won't work
  with the new expressions
  • Loading branch information
pawamoy committed Aug 7, 2023
1 parent e6aec02 commit 66c8ad5
Show file tree
Hide file tree
Showing 30 changed files with 1,482 additions and 1,236 deletions.
39 changes: 2 additions & 37 deletions docs/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -339,41 +339,9 @@
}
],
"$defs": {
"name": {
"type": "object",
"properties": {
"source": {
"title": "The annotation as written in the source code.",
"markdownDescription": "https://mkdocstrings.github.io/griffe/reference/griffe/dataclasses/#griffe.expressions.Name",
"type": "string"
},
"full": {
"title": "The full path of the .",
"markdownDescription": "https://mkdocstrings.github.io/griffe/reference/griffe/dataclasses/#griffe.expressions.Name",
"type": "string"
}
},
"additionalProperties": false,
"required": [
"source",
"full"
]
},
"expression": {
"type": "array",
"items": {
"oneOf": [
{
"type": "string"
},
{
"$ref": "#/$defs/name"
},
{
"$ref": "#/$defs/expression"
}
]
}
"type": "object",
"additionalProperties": true
},
"annotation": {
"oneOf": [
Expand All @@ -383,9 +351,6 @@
{
"type": "string"
},
{
"$ref": "#/$defs/name"
},
{
"$ref": "#/$defs/expression"
}
Expand Down
6 changes: 3 additions & 3 deletions src/griffe/agents/inspector.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
from pathlib import Path

from griffe.docstrings.parsers import Parser
from griffe.expressions import Expression, Name
from griffe.expressions import Expr


empty = Signature.empty
Expand Down Expand Up @@ -405,7 +405,7 @@ def inspect_attribute(self, node: ObjectNode) -> None:
"""
self.handle_attribute(node)

def handle_attribute(self, node: ObjectNode, annotation: str | Name | Expression | None = None) -> None:
def handle_attribute(self, node: ObjectNode, annotation: str | Expr | None = None) -> None:
"""Handle an attribute.
Parameters:
Expand Down Expand Up @@ -478,7 +478,7 @@ def _convert_parameter(parameter: SignatureParameter, parent: Module | Class) ->
return Parameter(name, annotation=annotation, kind=kind, default=default)


def _convert_object_to_annotation(obj: Any, parent: Module | Class) -> str | Name | Expression | None:
def _convert_object_to_annotation(obj: Any, parent: Module | Class) -> str | Expr | None:
# even when *we* import future annotations,
# the object from which we get a signature
# can come from modules which did *not* import them,
Expand Down
12 changes: 6 additions & 6 deletions src/griffe/agents/nodes/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@
ast_siblings,
)
from griffe.agents.nodes._docstrings import get_docstring
from griffe.agents.nodes._expressions import (
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_call_keyword_arguments
from griffe.agents.nodes._runtime import ObjectKind, ObjectNode
from griffe.agents.nodes._values import get_value, safe_get_value
from griffe.expressions import (
get_annotation,
get_base_class,
get_condition,
Expand All @@ -25,11 +30,6 @@
safe_get_condition,
safe_get_expression,
)
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_call_keyword_arguments
from griffe.agents.nodes._runtime import ObjectKind, ObjectNode
from griffe.agents.nodes._values import get_value, safe_get_value

__all__ = [
"ast_children",
Expand Down
23 changes: 11 additions & 12 deletions src/griffe/agents/nodes/_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@

import ast
from contextlib import suppress
from functools import partial
from typing import TYPE_CHECKING, Any, Callable

from griffe.agents.nodes._values import get_value
from griffe.expressions import Name
from griffe.expressions import ExprName
from griffe.logger import LogLevel, get_logger

if TYPE_CHECKING:
Expand All @@ -18,32 +17,32 @@
logger = get_logger(__name__)


def _extract_constant(node: ast.Constant, parent: Module) -> list[str | Name]:
def _extract_constant(node: ast.Constant, parent: Module) -> list[str | ExprName]:
return [node.value]


def _extract_name(node: ast.Name, parent: Module) -> list[str | Name]:
return [Name(node.id, partial(parent.resolve, node.id))]
def _extract_name(node: ast.Name, parent: Module) -> list[str | ExprName]:
return [ExprName(node.id, parent)]


def _extract_starred(node: ast.Starred, parent: Module) -> list[str | Name]:
def _extract_starred(node: ast.Starred, parent: Module) -> list[str | ExprName]:
return _extract(node.value, parent)


def _extract_sequence(node: ast.List | ast.Set | ast.Tuple, parent: Module) -> list[str | Name]:
def _extract_sequence(node: ast.List | ast.Set | ast.Tuple, parent: Module) -> list[str | ExprName]:
sequence = []
for elt in node.elts:
sequence.extend(_extract(elt, parent))
return sequence


def _extract_binop(node: ast.BinOp, parent: Module) -> list[str | Name]:
def _extract_binop(node: ast.BinOp, parent: Module) -> list[str | ExprName]:
left = _extract(node.left, parent)
right = _extract(node.right, parent)
return left + right


_node_map: dict[type, Callable[[Any, Module], list[str | Name]]] = {
_node_map: dict[type, Callable[[Any, Module], list[str | ExprName]]] = {
ast.Constant: _extract_constant,
ast.Name: _extract_name,
ast.Starred: _extract_starred,
Expand All @@ -54,11 +53,11 @@ def _extract_binop(node: ast.BinOp, parent: Module) -> list[str | Name]:
}


def _extract(node: ast.AST, parent: Module) -> list[str | Name]:
def _extract(node: ast.AST, parent: Module) -> list[str | ExprName]:
return _node_map[type(node)](node, parent)


def get__all__(node: ast.Assign | ast.AugAssign, parent: Module) -> list[str | Name]:
def get__all__(node: ast.Assign | ast.AugAssign, parent: Module) -> list[str | ExprName]:
"""Get the values declared in `__all__`.
Parameters:
Expand All @@ -77,7 +76,7 @@ def safe_get__all__(
node: ast.Assign | ast.AugAssign,
parent: Module,
log_level: LogLevel = LogLevel.debug, # TODO: set to error when we handle more things
) -> list[str | Name]:
) -> list[str | ExprName]:
"""Safely (no exception) extract values in `__all__`.
Parameters:
Expand Down
Loading

0 comments on commit 66c8ad5

Please sign in to comment.