Skip to content

Commit

Permalink
Skip class scopes when resolving nonlocal references (#4943)
Browse files Browse the repository at this point in the history
  • Loading branch information
charliermarsh authored Jun 7, 2023
1 parent 6950c93 commit f17282d
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 2 deletions.
19 changes: 19 additions & 0 deletions crates/ruff/resources/test/fixtures/pyflakes/F841_0.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,22 @@ def f(x: int):
def f():
if any((key := (value := x)) for x in ["ok"]):
print(key)


def f() -> None:
is_connected = False

class Foo:
@property
def is_connected(self):
nonlocal is_connected
return is_connected

def do_thing(self):
# This should resolve to the `is_connected` in the function scope.
nonlocal is_connected
print(is_connected)

obj = Foo()
obj.do_thing()

4 changes: 2 additions & 2 deletions crates/ruff/src/checkers/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,14 +291,14 @@ where
}

// Mark the binding in the defining scopes as used too. (Skip the global scope
// and the current scope.)
// and the current scope, and, per standard resolution rules, any class scopes.)
for (name, range) in names.iter().zip(ranges.iter()) {
let binding_id = self
.semantic_model
.scopes
.ancestors(self.semantic_model.scope_id)
.skip(1)
.take_while(|scope| !scope.kind.is_module())
.filter(|scope| !(scope.kind.is_module() || scope.kind.is_class()))
.find_map(|scope| scope.get(name.as_str()));

if let Some(binding_id) = binding_id {
Expand Down

0 comments on commit f17282d

Please sign in to comment.