distinguish references from definitions in infer_nonlocal

The initial implementation of `infer_nonlocal` landed in
https://github.com/astral-sh/ruff/pull/19112 fails to report an error
for this example:

```py
x = 1
def f():
    # This is only a usage of `x`, not a definition. It shouldn't be
    # enough to make the `nonlocal` statement below allowed.
    print(x)
    def g():
        nonlocal x
```

Fix this by continuing to walk enclosing scopes when the place we've
found isn't bound, declared, or `nonlocal`.
This commit is contained in:
Jack O'Connor 2025-07-14 14:40:58 -07:00
parent 00e7d1ffd6
commit a357a68fc9
3 changed files with 17 additions and 5 deletions

View file

@ -141,6 +141,12 @@ def f():
global x
def g():
nonlocal x # error: [invalid-syntax] "no binding for nonlocal `x` found"
def f():
# A *use* of `x` in an enclosing scope isn't good enough. There needs to be a binding.
print(x)
def g():
nonlocal x # error: [invalid-syntax] "no binding for nonlocal `x` found"
```
A class-scoped `x` also doesn't work: