Repository navigation
add test for False positive with overloaded async iterators #2873 - #2939
asukaminato0721 wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
Fixes a false-positive overload/yield error involving async generator implementations with overload stubs returning AsyncIterator[...], and unions of async-iterator return types.
Changes:
- Normalize overload return signatures when the implementation is an async generator (so overloads don’t remain wrapped as
Coroutine[..., AsyncIterator[...]]). - Update generator/async-generator decomposition to handle
Uniontypes member-by-member and union the decomposed components. - Add a regression test covering overloaded async iterator returns and yield behavior.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| pyrefly/lib/test/overload.rs | Adds a regression test reproducing issue #2873 with overloaded async generator returning AsyncIterator[...]. |
| pyrefly/lib/alt/unwrap.rs | Decomposes generator / async generator types across union members and unions their yield/send/return components. |
| pyrefly/lib/alt/function.rs | Normalizes overload signatures for async generator implementations before overload consistency checking. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
stroxler
left a comment
There was a problem hiding this comment.
Thanks!
Based on AI review, I think this needs some more work. The mypy primer changes are encouraging but AI review found a correctness regression, and the intended fix changes overload semantics rather than merely removing a false positive.
Review notes:
Genuine coroutine returns are incorrectly erased
pyrefly/pyrefly/lib/alt/function.rs
Lines 2231 to 2249 in 2d29f0c
decompose_async_generator(&impl_sig.ret) checks return-type compatibility, not whether the implementation is an async generator. It succeeds for Any, so a valid synchronous coroutine factory annotated -> Any triggers normalization.
Consequently:
- Async overloads returning
AsyncIterator[T]lose their effectiveCoroutinewrapper. - Ordinary
defoverloads explicitly returningCoroutine[..., AsyncIterator[T]]are also rewritten. - Valid
await factory(...)calls become “not awaitable” errors. Genuine overload inconsistencies can disappear.
I reproduced both cases against exact base/head builds. At minimum, require actual generator provenance and distinguish implicit async wrapping from explicitly declared coroutine returns. A syntactic guard also avoids allocating solver variables and running subtype checks for unrelated synchronous overloads.
Overload meanings depend on the implementation
pyrefly/pyrefly/lib/alt/function.rs
Lines 418 to 427 in 2d29f0c
Identical declarations remain coroutine-returning in stubs/protocols but become iterator-returning alongside a yielding implementation. That conflicts with the [overload specification](https://typing.python.org/en/latest/spec/overload.html#invalid-overload-definitions).
My recommendation is to preserve the signatures and use ordinary def for the iterator-returning overload declarations. The PR’s regression snippet already passes the unchanged base with just that adjustment; mypy agrees.
Either remove the union hunk or cover it in tests
The original snippet has no yield errors on the exact base. Existing yield checking already splits top-level unions through HintRef. The unwrap.rs change needs its own failing regression demonstrating why it is necessary.
Note that splitting this into a separate PR might be a good option.
|
According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅ |
stroxler
left a comment
There was a problem hiding this comment.
Review automatically exported from Phabricator review in Meta.
|
This pull request has been merged in 5f3385f. |
Summary
Fixes #2873
The change has two parts.overload signatures are normalized when the implementation is an async generator, so async def overload stubs returningAsyncIterator[...]no longer stay wrapped asCoroutine[..., AsyncIterator[...]].generator decomposition now handles unions member-by-member, which fixes the bogus yield Patch() vs FullState error fromAsyncIterator[Patch] | AsyncIterator[FullState].Test Plan
add test