Fix syntax error false positives for await outside functions (#21763)

## Summary

Fixes #21750 and a related bug in `PLE1142`. We were not properly
considering generators to be valid `await` contexts, which caused the
`F704` issue. One of the tests I added for this also uncovered an issue
in `PLE1142` for comprehensions nested within async generators because
we were only checking the current scope rather than traversing the
nested context.

## Test Plan

Both of these rules are implemented as semantic syntax errors, so I
added tests (and fixes) in both Ruff and ty.
This commit is contained in:
Brent Westbrook
2025-12-02 16:02:02 -05:00
committed by GitHub
parent 392a8e4e50
commit 2250fa6f98
9 changed files with 147 additions and 16 deletions

View File

@@ -143,6 +143,10 @@ await C()
def f():
# error: [invalid-syntax] "`await` outside of an asynchronous function"
await C()
(await cor async for cor in f()) # ok
(await cor for cor in f()) # ok
([await c for c in cor] async for cor in f()) # ok
```
Generators are evaluated lazily, so `await` is allowed, even outside of a function.

View File

@@ -2845,6 +2845,11 @@ impl SemanticSyntaxContext for SemanticIndexBuilder<'_, '_> {
match scope.kind() {
ScopeKind::Class => return false,
ScopeKind::Function | ScopeKind::Lambda => return true,
ScopeKind::Comprehension
if matches!(scope.node(), NodeWithScopeKind::GeneratorExpression(_)) =>
{
return true;
}
ScopeKind::Comprehension
| ScopeKind::Module
| ScopeKind::TypeAlias
@@ -2894,11 +2899,14 @@ impl SemanticSyntaxContext for SemanticIndexBuilder<'_, '_> {
matches!(kind, ScopeKind::Function | ScopeKind::Lambda)
}
fn in_generator_scope(&self) -> bool {
matches!(
self.scopes[self.current_scope()].node(),
NodeWithScopeKind::GeneratorExpression(_)
)
fn in_generator_context(&self) -> bool {
for scope_info in &self.scope_stack {
let scope = &self.scopes[scope_info.file_scope_id];
if matches!(scope.node(), NodeWithScopeKind::GeneratorExpression(_)) {
return true;
}
}
false
}
fn in_notebook(&self) -> bool {