pylint-dev / pylint

It's not just a linter that annoys you!
https://pylint.readthedocs.io/en/latest/
GNU General Public License v2.0
5.26k stars 1.12k forks source link

False positive `assigning-non-slot` error for inherited descriptor when slots are used. #8053

Open Hubrrr88 opened 1 year ago

Hubrrr88 commented 1 year ago

Bug description

Following code produces a false positive: The function copy() in the derived "Child" class even has a casting method used, to give type hints.

from typing import Any, cast

class MyDescriptor:
    __slots__ = ("offset", "value")

    def __init__(self, offset: int) -> None:
        self.offset = offset
        self.value = 0

    def __set__(self, instance: Any, value: int) -> None:
        self.value = value

    def __get__(self, instance: Any, owner: Any) -> int:
        return self.value

class Parent:
    __slots__ = ()
    MyParentField = MyDescriptor(0)

    def copy(self) -> "Parent":
        return type(self)()

class Child(Parent):
    __slots__ = ()
    MyChildField = MyDescriptor(1)

    def copy(self) -> "Child":
        return cast(Child, super().copy())

if __name__ == '__main__':
    child = Child()
    child.MyChildField = 0
    child.MyParentField = 0

    child_copy = child.copy()
    child_copy.MyParentField = 0
    child_copy.MyChildField = 0

Configuration

No response

Command used

pylint --errors-only main.py

Pylint output

************* Module main
main.py:41:4: E0237: Assigning to attribute 'MyChildField' not defined in class slots (assigning-non-slot)

Expected behavior

No error should be produced as the code runs perfectly fine.

Pylint version

pylint 2.15.10
astroid 2.13.2
Python 3.9.5 (default, Oct  6 2021, 16:12:40)
[Clang 13.0.0 (clang-1300.0.29.3)]

OS / Environment

macOS Ventura 13.1

Additional dependencies

No response

mbyrnepr2 commented 1 year ago

Thanks @Hubrrr88 I can reproduce that. Looks like this is_class_attr function only checks the given class & not its parents also.

mbyrnepr2 commented 1 year ago

Edited the title to remove the reference to type-hints as they don't seem to affect the situation.