Skip to content

Commit 66c8ad5

Browse files
committed
refactor: Improve expressions
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
1 parent e6aec02 commit 66c8ad5

30 files changed

Lines changed: 1482 additions & 1236 deletions

docs/schema.json

Lines changed: 2 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -339,41 +339,9 @@
339339
}
340340
],
341341
"$defs": {
342-
"name": {
343-
"type": "object",
344-
"properties": {
345-
"source": {
346-
"title": "The annotation as written in the source code.",
347-
"markdownDescription": "https://mkdocstrings.github.io/griffe/reference/griffe/dataclasses/#griffe.expressions.Name",
348-
"type": "string"
349-
},
350-
"full": {
351-
"title": "The full path of the .",
352-
"markdownDescription": "https://mkdocstrings.github.io/griffe/reference/griffe/dataclasses/#griffe.expressions.Name",
353-
"type": "string"
354-
}
355-
},
356-
"additionalProperties": false,
357-
"required": [
358-
"source",
359-
"full"
360-
]
361-
},
362342
"expression": {
363-
"type": "array",
364-
"items": {
365-
"oneOf": [
366-
{
367-
"type": "string"
368-
},
369-
{
370-
"$ref": "#/$defs/name"
371-
},
372-
{
373-
"$ref": "#/$defs/expression"
374-
}
375-
]
376-
}
343+
"type": "object",
344+
"additionalProperties": true
377345
},
378346
"annotation": {
379347
"oneOf": [
@@ -383,9 +351,6 @@
383351
{
384352
"type": "string"
385353
},
386-
{
387-
"$ref": "#/$defs/name"
388-
},
389354
{
390355
"$ref": "#/$defs/expression"
391356
}

src/griffe/agents/inspector.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
from pathlib import Path
4949

5050
from griffe.docstrings.parsers import Parser
51-
from griffe.expressions import Expression, Name
51+
from griffe.expressions import Expr
5252

5353

5454
empty = Signature.empty
@@ -405,7 +405,7 @@ def inspect_attribute(self, node: ObjectNode) -> None:
405405
"""
406406
self.handle_attribute(node)
407407

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

480480

481-
def _convert_object_to_annotation(obj: Any, parent: Module | Class) -> str | Name | Expression | None:
481+
def _convert_object_to_annotation(obj: Any, parent: Module | Class) -> str | Expr | None:
482482
# even when *we* import future annotations,
483483
# the object from which we get a signature
484484
# can come from modules which did *not* import them,

src/griffe/agents/nodes/__init__.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,12 @@
1515
ast_siblings,
1616
)
1717
from griffe.agents.nodes._docstrings import get_docstring
18-
from griffe.agents.nodes._expressions import (
18+
from griffe.agents.nodes._imports import relative_to_absolute
19+
from griffe.agents.nodes._names import get_instance_names, get_name, get_names
20+
from griffe.agents.nodes._parameters import get_call_keyword_arguments
21+
from griffe.agents.nodes._runtime import ObjectKind, ObjectNode
22+
from griffe.agents.nodes._values import get_value, safe_get_value
23+
from griffe.expressions import (
1924
get_annotation,
2025
get_base_class,
2126
get_condition,
@@ -25,11 +30,6 @@
2530
safe_get_condition,
2631
safe_get_expression,
2732
)
28-
from griffe.agents.nodes._imports import relative_to_absolute
29-
from griffe.agents.nodes._names import get_instance_names, get_name, get_names
30-
from griffe.agents.nodes._parameters import get_call_keyword_arguments
31-
from griffe.agents.nodes._runtime import ObjectKind, ObjectNode
32-
from griffe.agents.nodes._values import get_value, safe_get_value
3333

3434
__all__ = [
3535
"ast_children",

src/griffe/agents/nodes/_all.py

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,10 @@
44

55
import ast
66
from contextlib import suppress
7-
from functools import partial
87
from typing import TYPE_CHECKING, Any, Callable
98

109
from griffe.agents.nodes._values import get_value
11-
from griffe.expressions import Name
10+
from griffe.expressions import ExprName
1211
from griffe.logger import LogLevel, get_logger
1312

1413
if TYPE_CHECKING:
@@ -18,32 +17,32 @@
1817
logger = get_logger(__name__)
1918

2019

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

2423

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

2827

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

3231

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

3938

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

4544

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

5655

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

6059

61-
def get__all__(node: ast.Assign | ast.AugAssign, parent: Module) -> list[str | Name]:
60+
def get__all__(node: ast.Assign | ast.AugAssign, parent: Module) -> list[str | ExprName]:
6261
"""Get the values declared in `__all__`.
6362
6463
Parameters:
@@ -77,7 +76,7 @@ def safe_get__all__(
7776
node: ast.Assign | ast.AugAssign,
7877
parent: Module,
7978
log_level: LogLevel = LogLevel.debug, # TODO: set to error when we handle more things
80-
) -> list[str | Name]:
79+
) -> list[str | ExprName]:
8180
"""Safely (no exception) extract values in `__all__`.
8281
8382
Parameters:

0 commit comments

Comments
 (0)