-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Closed
Labels
bugSomething isn't workingSomething isn't working
Description
Summary
By default, __class__ within a method definition is a free variable and its corresponding cell variable is always bound. unused-variable (F841) and nonlocal-without-binding (PLE0117) have false positives because they don’t understand this special case. This is probably a general problem with how Ruff resolves bindings which could affect other rules.
$ cat >f841_ple0117.py <<'# EOF'
class A:
x = 1
class B:
x = 2
class C(A, B):
def set_class(self, cls):
nonlocal __class__
if cls not in type(self).__mro__:
raise ValueError(f"Invalid superclass: {cls}")
__class__ = cls
def get_class(self):
return __class__
def __getattribute__(self, attr):
if attr in vars(type(self)):
return object.__getattribute__(self, attr)
if attr in vars(__class__):
mro = type(self).__mro__
return getattr(super(mro[mro.index(__class__) - 1], self), attr)
return getattr(super(), attr)
c = C()
print(c.x)
c.set_class(B)
print(c.x)
# EOF
$ python f841_ple0117.py
1
2
$ ruff --isolated check --select F841,PLE0117 f841_ple0117.py --output-format concise -q
f841_ple0117.py:11:18: PLE0117 Nonlocal name `__class__` found without binding
f841_ple0117.py:14:9: F841 Local variable `__class__` is assigned to but never used
$ ruff --isolated check --select F841,PLE0117 f841_ple0117.py -s --unsafe-fixes --fix
$ python f841_ple0117.py
1
1That PLE0117 diagnostic is a false positive because __class__ does have a binding; it just isn’t explicit in the source code. That F841 diagnostic is a false positive because __class__ is not a local variable.
Version
ruff 0.11.12 (aee3af0 2025-05-29)
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working