fix False positive with overloaded async iterators #2873#2939
fix False positive with overloaded async iterators #2873#2939asukaminato0721 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.
This comment has been minimized.
This comment has been minimized.
|
Diff from mypy_primer, showing the effect of this PR on open source code: steam.py (https://github.com/Gobot1234/steam.py)
- ERROR steam/leaderboard.py:101:15-22: Overload return type `Coroutine[Unknown, Unknown, AsyncGenerator[LeaderboardUser]]` is not assignable to implementation return type `AsyncGenerator[LeaderboardUser]` [inconsistent-overload]
- ERROR steam/leaderboard.py:110:15-22: Overload return type `Coroutine[Unknown, Unknown, AsyncGenerator[LeaderboardUser]]` is not assignable to implementation return type `AsyncGenerator[LeaderboardUser]` [inconsistent-overload]
prefect (https://github.com/PrefectHQ/prefect)
+ ERROR src/prefect/server/models/task_runs.py:138:8-21: Object of class `NoneType` has no attribute `created` [missing-attribute]
+ ERROR src/prefect/server/models/task_runs.py:141:25-33: Object of class `NoneType` has no attribute `id` [missing-attribute]
+ ERROR src/prefect/server/models/task_runs.py:147:12-17: Returned type `TaskRun | None` is not assignable to declared return type `TaskRun` [bad-return]
|
Primer Diff Classification❌ 1 regression(s) | ✅ 1 improvement(s) | 2 project(s) total | +3, -2 errors 1 regression(s) across prefect. error kinds:
Detailed analysis❌ Regression (1)prefect (+3)
✅ Improvement (1)steam.py (-2)
The implementation (line 114) is also declared as This creates the type mismatch: pyrefly sees the overload stubs as having return type
Suggested fixesSummary: The decompose_async_generator() change in unwrap.rs adds a Type::Union match arm that short-circuits before calling is_subset_eq/fresh_var for non-async-generator unions, potentially affecting solver constraint state and causing narrowing regressions in prefect. 1. In
Was this helpful? React with 👍 or 👎 Classification by primer-classifier (2 LLM) |
Summary
Fixes #2873
The change has two parts.
overload signatures are normalized when the implementation is an async generator, so async def overload stubs returning
AsyncIterator[...]no longer stay wrapped asCoroutine[..., AsyncIterator[...]].generator decomposition now handles unions member-by-member, which fixes the bogus yield Patch() vs FullState error from
AsyncIterator[Patch] | AsyncIterator[FullState].Test Plan
add test