Skip to content

Ruff picks wrong scope for variable #4486

@notatallshaw

Description

@notatallshaw

Specifically, Ruff incorrectly identifies the scope a variable is chosen from when it's inside a comprehension inside a class inside a function and a variable with the same name exists inside the class scope.

Here is shortest code to reproduce this example, I named it scopetest.py:

def f():
    b = 'Function Scope'
    class C:
        b = 'Class Scope'
        d = [b for _ in range(1)]
    return C

print(f().d[0])  # Prints "Function Scope"

Running Ruff:

> ruff --version
ruff 0.0.267
> ruff scopetest.py
scopetest.py:2:5: F841 [*] Local variable `b` is assigned to but never used
Found 1 error.

If I run ruff with --fix it deletes the line that b is sourced from causing the code to now throw an exception.

The reason b is scoping from the function scope and not the class scope is that generators / comprehensions implicitly create an anonymous function and source their scope from locals, non-locals, globals, and builtins and skip the class scope as all other functions do.

I came across this testing different versions of code posted here where the Steering Council has decided to keep the behavior as-is for at least Python 3.12.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions