|
10 | 10 | from itertools import zip_longest
|
11 | 11 | from typing import TYPE_CHECKING, Any, Callable, Iterable, Iterator, Sequence
|
12 | 12 |
|
| 13 | +from griffe.agents.nodes import get_parameters |
13 | 14 | from griffe.enumerations import ParameterKind
|
14 | 15 | from griffe.exceptions import NameResolutionError
|
15 | 16 | from griffe.logger import LogLevel, get_logger
|
@@ -486,8 +487,34 @@ class ExprLambda(Expr):
|
486 | 487 | """Lambda's body."""
|
487 | 488 |
|
488 | 489 | def iterate(self, *, flat: bool = True) -> Iterator[str | Expr]: # noqa: D102
|
489 |
| - yield "lambda " |
490 |
| - yield from _join(self.parameters, ", ", flat=flat) |
| 490 | + pos_only = False |
| 491 | + pos_or_kw = False |
| 492 | + kw_only = False |
| 493 | + length = len(self.parameters) |
| 494 | + yield "lambda" |
| 495 | + if length: |
| 496 | + yield " " |
| 497 | + for index, parameter in enumerate(self.parameters, 1): |
| 498 | + if parameter.kind is ParameterKind.positional_only: |
| 499 | + pos_only = True |
| 500 | + elif parameter.kind is ParameterKind.var_positional: |
| 501 | + yield "*" |
| 502 | + elif parameter.kind is ParameterKind.var_keyword: |
| 503 | + yield "**" |
| 504 | + elif parameter.kind is ParameterKind.positional_or_keyword and not pos_or_kw: |
| 505 | + pos_or_kw = True |
| 506 | + elif parameter.kind is ParameterKind.keyword_only and not kw_only: |
| 507 | + kw_only = True |
| 508 | + yield "*, " |
| 509 | + if parameter.kind is not ParameterKind.positional_only and pos_only: |
| 510 | + pos_only = False |
| 511 | + yield "/, " |
| 512 | + yield parameter.name |
| 513 | + if parameter.default and parameter.kind not in (ParameterKind.var_positional, ParameterKind.var_keyword): |
| 514 | + yield "=" |
| 515 | + yield from _yield(parameter.default, flat=flat) |
| 516 | + if index < length: |
| 517 | + yield ", " |
491 | 518 | yield ": "
|
492 | 519 | yield from _yield(self.body, flat=flat)
|
493 | 520 |
|
@@ -587,13 +614,13 @@ def iterate(self, *, flat: bool = True) -> Iterator[str | Expr]: # noqa: D102
|
587 | 614 | class ExprParameter(Expr):
|
588 | 615 | """Parameters in function signatures like `a: int = 0`."""
|
589 | 616 |
|
590 |
| - kind: str |
591 |
| - """Parameter kind.""" |
592 |
| - name: str | None = None |
| 617 | + name: str |
593 | 618 | """Parameter name."""
|
| 619 | + kind: ParameterKind = ParameterKind.positional_or_keyword |
| 620 | + """Parameter kind.""" |
594 | 621 | annotation: Expr | None = None
|
595 | 622 | """Parameter type."""
|
596 |
| - default: Expr | None = None |
| 623 | + default: str | Expr | None = None |
597 | 624 | """Parameter default."""
|
598 | 625 |
|
599 | 626 |
|
@@ -924,10 +951,19 @@ def _build_keyword(node: ast.keyword, parent: Module | Class, function: Expr | N
|
924 | 951 |
|
925 | 952 |
|
926 | 953 | def _build_lambda(node: ast.Lambda, parent: Module | Class, **kwargs: Any) -> Expr:
|
927 |
| - # FIXME: This needs better handling (all parameter kinds). |
928 | 954 | return ExprLambda(
|
929 |
| - [ExprParameter(ParameterKind.positional_or_keyword.value, arg.arg) for arg in node.args.args], |
930 |
| - _build(node.body, parent, **kwargs), |
| 955 | + parameters=[ |
| 956 | + ExprParameter( |
| 957 | + name=name, |
| 958 | + kind=kind, |
| 959 | + annotation=None, |
| 960 | + default=default |
| 961 | + if isinstance(default, str) |
| 962 | + else safe_get_expression(default, parent=parent, parse_strings=False), |
| 963 | + ) |
| 964 | + for name, _, kind, default in get_parameters(node.args) |
| 965 | + ], |
| 966 | + body=_build(node.body, parent, **kwargs), |
931 | 967 | )
|
932 | 968 |
|
933 | 969 |
|
|
0 commit comments