This commit is contained in:
Ruchir 2025-12-16 16:39:34 -05:00 committed by GitHub
commit d1851caf00
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 46 additions and 4 deletions

View File

@ -0,0 +1,27 @@
from __future__ import annotations
from typing import Callable
def demonstrate_bare_local_annotation():
x: int
print(x)
demonstrate_bare_local_annotation()
def make_closure_pair() -> tuple[Callable[[], int], Callable[[int], None]]:
x: int
def get_value() -> int:
return x
def set_value(new_value: int) -> None:
nonlocal x
x = new_value
return get_value, set_value
get_value, set_value = make_closure_pair()
set_value(123)
print(get_value())

View File

@ -168,6 +168,7 @@ mod tests {
#[test_case(Rule::UndefinedName, Path::new("F821_31.py"))] #[test_case(Rule::UndefinedName, Path::new("F821_31.py"))]
#[test_case(Rule::UndefinedName, Path::new("F821_32.pyi"))] #[test_case(Rule::UndefinedName, Path::new("F821_32.pyi"))]
#[test_case(Rule::UndefinedName, Path::new("F821_33.py"))] #[test_case(Rule::UndefinedName, Path::new("F821_33.py"))]
#[test_case(Rule::UndefinedName, Path::new("F821_34.py"))]
#[test_case(Rule::UndefinedExport, Path::new("F822_0.py"))] #[test_case(Rule::UndefinedExport, Path::new("F822_0.py"))]
#[test_case(Rule::UndefinedExport, Path::new("F822_0.pyi"))] #[test_case(Rule::UndefinedExport, Path::new("F822_0.pyi"))]
#[test_case(Rule::UndefinedExport, Path::new("F822_1.py"))] #[test_case(Rule::UndefinedExport, Path::new("F822_1.py"))]
@ -3667,7 +3668,7 @@ lambda: fu
name: str name: str
print(name) print(name)
", ",
&[Rule::UndefinedName], &[],
); );
flakes( flakes(
r" r"

View File

@ -0,0 +1,4 @@
---
source: crates/ruff_linter/src/rules/pyflakes/mod.rs
---

View File

@ -476,9 +476,19 @@ impl<'a> SemanticModel<'a> {
// The `name` in `print(name)` should be treated as unresolved, but the `name` in // The `name` in `print(name)` should be treated as unresolved, but the `name` in
// `name: str` should be treated as used. // `name: str` should be treated as used.
// //
// Stub files are an exception. In a stub file, it _is_ considered valid to // There are two exceptions to this rule:
// resolve to a type annotation. // 1. Stub files. In a stub file, it _is_ considered valid to resolve to a
BindingKind::Annotation if !self.in_stub_file() => continue, // type annotation.
// 2. Bare annotations inside functions. Per PEP 526, these create local
// variables.
BindingKind::Annotation
if !self.in_stub_file()
&& !self.scopes[self.bindings[binding_id].scope]
.kind
.is_function() =>
{
continue;
}
// If it's a deletion, don't treat it as resolved, since the name is now // If it's a deletion, don't treat it as resolved, since the name is now
// unbound. For example, given: // unbound. For example, given: