Skip to content

Reference implementation for PEP 828#145716

Draft
ZeroIntensity wants to merge 56 commits intopython:mainfrom
ZeroIntensity:async-yield-from
Draft

Reference implementation for PEP 828#145716
ZeroIntensity wants to merge 56 commits intopython:mainfrom
ZeroIntensity:async-yield-from

Conversation

@ZeroIntensity
Copy link
Copy Markdown
Member

Not a real PR; this will be linked in the PEP so people can comment on the diff.

Comment thread Python/ast_preprocess.c Outdated
Comment thread Python/ast_unparse.c Outdated
@read-the-docs-community
Copy link
Copy Markdown

read-the-docs-community Bot commented May 2, 2026

Documentation build overview

📚 cpython-previews | 🛠️ Build #32516176 | 📁 Comparing c3e3329 against main (b1d6231)

  🔍 Preview build  

40 files changed · ± 40 modified

± Modified

ZeroIntensity and others added 21 commits May 2, 2026 17:35
Implement `visit_AsyncYieldFrom` in Python unparse
Rename every test in `TestPEP828Operation` and `TestInterestingEdgeCases`
to its `test_yield_from` sibling's name with an `_ayf` suffix, so the two
suites map onto each other mechanically.

Add `TestParityWithPEP380`, which uses `assert_parity` to enforce that
each mirrored class is in symmetric parity: every PEP 380 test has a
corresponding `_ayf` variant, and every variant has a PEP 380 base. A
missing variant or an unmatched extra both fail the parity test.

Move `test_delegate_exception` (the only PEP 828-only test) into a new
`TestPEP828Extras` class. Tests that have no PEP 380 analogue belong
there; the parity classes stay strictly mirrored.

Lazy-import `test_yield_from` so the parity machinery doesn't pull it in
unless the parity tests actually run.
Note the `_ayf` naming convention, the 1:1 parity check enforced by
`TestParityWithPEP380`, and where PEP 828-only tests belong.
Mirrored test method names already match their PEP 380 counterparts via
the `_ayf` suffix. The descriptions and subTest labels now use the async
API names (`asend`, `aclose`, `athrow`, `anext`) so it is clear which
operation each test exercises.

Class docstrings on `TestPEP828Operation` and `TestInterestingEdgeCases`
now state that they mirror their `test_yield_from` counterparts.
The previous wording instructed maintainers to keep the two suites in
sync manually; that contract is now enforced by `TestParityWithPEP380`
on the async side, so the cross-reference can stay minimal.
The `yielded_first` / `yielded_second` / `returned` placeholders were
created with `object()`, which renders as a generic repr in failure
output. Switching to `sentinel(...)` keeps the same identity semantics
while giving each marker a meaningful repr.
Print each offender on its own line, labelled with which side is missing
the counterpart, instead of dumping two summary sentences with embedded
list reprs. Factor the duplicated set-comprehension into a small inner
helper so the assertion body is also a touch shorter.

Sample failure (deleting one mirrored test, adding two extras):

    TestPEP828Operation is not a 1:1 mirror of TestPEP380Operation (suffix '_ayf'):
        missing in TestPEP828Operation: test_yield_from_empty_ayf
        no counterpart in TestPEP380Operation: test_made_up_extra_ayf
        no counterpart in TestPEP380Operation: test_other_extra_ayf
When the mirrored classes share an unqualified name (e.g. both PEP 380
and PEP 828 have a `TestInterestingEdgeCases`), the failure message
talked about the class on both sides as if it were the same class. Use
`module.qualname` so each side is unambiguous.
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.

2 participants