Skip to content

Python: Add support for PEP-798#21695

Draft
tausbn wants to merge 13 commits intomainfrom
tausbn/python-add-support-for-pep-798
Draft

Python: Add support for PEP-798#21695
tausbn wants to merge 13 commits intomainfrom
tausbn/python-add-support-for-pep-798

Conversation

@tausbn
Copy link
Copy Markdown
Contributor

@tausbn tausbn commented Apr 10, 2026

WIP. Needs #21694 to be merged first as it is stacked on top of it.

tausbn added 13 commits April 10, 2026 13:50
As defined in PEP-810. We implement this in much the same way as how we
handle `async` annotations currently. The relevant nodes get an
`is_lazy` field that defaults to being false.
Otherwise these will disappear every time we regenerate the AST.
Adds a new `isLazy` predicate to the relevant classes, and adds the
relevant dbscheme (and up/downgrade) changes. On upgrades we do nothing,
and on downgrades we remove the `is_lazy` bits.
This is the easy part -- we just allow `dictionary_splat` or
`list_splat` to appear in the same place as the expression.
First, we extend the various location overriding hacks to also accept
list and dict splats in various places. Having done this, we then have
to tackle how to actually desugar these new comprehension forms (as this
is what we currently do for the old forms).

As a reminder, a list comprehension like `[x for x in y]` currently gets
desugared into a small local function, something like

```python
def listcomp(a):
    for x in a:
        yield x
listcomp(y)
```

For `[*x for x in y]`, the behaviour we want is that we unpack `x`
before yielding its elements in turn. This is essentially what we would
get if we were to use `yield from x` instead of `yield x` in the above
desugaring, so that's what we do. This also works for set
comprehensions.

For dict comprehensions, it's slightly more complicated. Here, the
generator function instead yields a stream of `(key, value)` tuples.
(And apparently the old parser got this wrong and emitted `(value, key)`
pairs instead, which we faithfully recreated in the new parser as well.
We fix that bug in both parsers while we're at it). So, a bare `yield
from` is not enough, we also need a `.items()` call to get the
double-starred expression to emit its items as a stream of tuples (that
we then `yield from`.

To make this (hopefully) less verbose in the implementation, we defer
the decision of whether to use `yield` or `yield from` by introducing a
`yield_kind` scoped variable that determines the type of the actual AST
node. And of course for dict comprehensions with unpacking we need to
synthesise the extra machinery mentioned above.

On the plus side, this means we don't have to mess with control-flow, as
the existing machinery should be able to handle the desugared syntax
just fine.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant