From 859a4d16e9e2e5473845d44a079b24f68522f559 Mon Sep 17 00:00:00 2001 From: mushitoriami Date: Wed, 1 Jul 2026 19:30:49 +0900 Subject: [PATCH] feat: Support unpacking in dict comprehensions Add support for Unpacking in Comprehensions, which is introduced in Python 3.15 (PEP 798). This PR also resolves the following failures in Python 3.15 environments type checking: ``` packages/griffelib/src/griffe/_internal/expressions.py:1264:16: error[invalid-argument-type] Argument to function `_build` is incorrect: Expected `AST`, found `expr | None` ``` ref: https://github.com/mkdocstrings/griffe/actions/runs/28114520110/job/83250363149#step:9:23 --- .../griffelib/src/griffe/_internal/expressions.py | 14 +++++++++----- packages/griffelib/tests/test_expressions.py | 11 +++++++++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/packages/griffelib/src/griffe/_internal/expressions.py b/packages/griffelib/src/griffe/_internal/expressions.py index 2916ba70..a07e0ae2 100644 --- a/packages/griffelib/src/griffe/_internal/expressions.py +++ b/packages/griffelib/src/griffe/_internal/expressions.py @@ -468,16 +468,20 @@ class ExprDictComp(Expr): key: str | Expr """Target key.""" - value: str | Expr + value: str | Expr | None """Target value.""" generators: Sequence[Expr] """Generators iterated on.""" def iterate(self, *, flat: bool = True) -> Iterator[str | Expr]: yield "{" - yield from _yield(self.key, flat=flat) - yield ": " - yield from _yield(self.value, flat=flat) + if self.value: + yield from _yield(self.key, flat=flat) + yield ": " + yield from _yield(self.value, flat=flat) + else: + yield "**" + yield from _yield(self.key, flat=flat) yield " " yield from _join(self.generators, " ", flat=flat) yield "}" @@ -1261,7 +1265,7 @@ def _build_dict(node: ast.Dict, parent: Module | Class, **kwargs: Any) -> Expr: def _build_dictcomp(node: ast.DictComp, parent: Module | Class, **kwargs: Any) -> Expr: return ExprDictComp( _build(node.key, parent, **kwargs), - _build(node.value, parent, **kwargs), + None if node.value is None else _build(node.value, parent, **kwargs), [_build(gen, parent, **kwargs) for gen in node.generators], ) diff --git a/packages/griffelib/tests/test_expressions.py b/packages/griffelib/tests/test_expressions.py index dab89b81..5edad128 100644 --- a/packages/griffelib/tests/test_expressions.py +++ b/packages/griffelib/tests/test_expressions.py @@ -311,3 +311,14 @@ def test_render_dict_with_unpacking() -> None: assert str(module["a"].value) == "{**base, 'x': 1}" assert str(module["b"].value) == "{**d1, **d2}" assert str(module["c"].value) == "{None: 1, 'y': 2}" + + +@pytest.mark.skipif(sys.version_info < (3, 15), reason="Unpackings in Comprehensions require Python 3.15+") +def test_render_dict_comprehension_with_unpacking() -> None: + """Docstring stub.""" + with temporary_visited_module( + """ + a = {**d for d in dicts} + """, + ) as module: + assert str(module["a"].value) == "{**d for d in dicts}"