ruff icon indicating copy to clipboard operation
ruff copied to clipboard

Feature Request: Warn when instance attribute shadows class attribute

Open alippai opened this issue 1 year ago • 7 comments

I suggest adding a linting rule to warn when an instance attribute shadows a class attribute of the same name. This can help prevent bugs from unintended overriding of class-level variables.

class A:
    x = 1
    def get_x(self):
        return self.x

a = A()
a.x = 2  # Shadows class attribute 'x'
print(a.get_x())  # Outputs 2, but class attribute 'x' is 1

In this example, assigning to a.x creates an instance attribute that overshadows the class attribute x. Accessing self.x in get_x now refers to the instance attribute, which might not be the intended behavior.

Similarly, the subclassing is error prone:

class Parent:
    def __init__(self):
        self.value = 'instance'

    def get_value(self):
        return self.value

class Child(Parent):
    value = 'class'  # Class attribute shadows instance attribute

c = Child()
print(c.get_value())  # Outputs 'instance'

alippai avatar Dec 28 '24 20:12 alippai

@MichaReiser this might be relevant here: https://github.com/astral-sh/ruff/pull/10891

alippai avatar Dec 28 '24 21:12 alippai

Thanks for opening this rule idea.

The main challenge with this rule is that it probably requires type inference, or at least more advanced analysis than what Ruff does today to be useful:

  • Ruff needs to understand that a is an instance of A
  • Ideally, Ruff understands that a is an instance of A even if A is defined in another file or if A is the result of a function call
  • Ruff needs to understand whether a.x is an instance attribute or not (I think that's doable because detecting class attributes is "easy enough).

MichaReiser avatar Dec 30 '24 09:12 MichaReiser

Can we use ty in ruff to implement this?

alippai avatar May 17 '25 23:05 alippai

Can we use ty in ruff to implement this?

Not today, no. Using ty in ruff requires fundamental changes to how ruff works internally. But it's on our long-term roadmap to bring the power of ty to ruff lint rules but we don't know yet how exactly we'll do that.

MichaReiser avatar May 18 '25 16:05 MichaReiser

@MichaReiser thanks! It’s exciting and everything seems to go in the best direction.

alippai avatar May 18 '25 17:05 alippai

@MichaReiser did ruff or ty change in this question? If there is an example for linting based on type inference, I’d give it a try

alippai avatar Dec 18 '25 04:12 alippai

No, Ruff isn't yet using ty's analysis engine

MichaReiser avatar Dec 18 '25 06:12 MichaReiser