Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PLE0237 false positive #10306

Closed
henryiii opened this issue Mar 9, 2024 · 3 comments · Fixed by #10348
Closed

PLE0237 false positive #10306

henryiii opened this issue Mar 9, 2024 · 3 comments · Fixed by #10348
Assignees
Labels
bug Something isn't working linter Related to the linter

Comments

@henryiii
Copy link
Contributor

henryiii commented Mar 9, 2024

Currently, PLE0237 will report "Attribute other is not defined in class's __slots__" on a class like this:

class A:
    __slots__ = ("pub",)

    def __init__(self) -> None:
        self.other = "hi"

Which is correct. But it also reports the same error on the following correct class:

class B:
    __slots__ = ("pub", "__dict__")

    def __init__(self) -> None:
        self.other = "hi"

This is incorrect; since the class has a __dict__ in it's __slots__, it has a dict to put other in. This is described in https://docs.python.org/3/reference/datamodel.html#slots (both __dict__ and __weakref__ can be declared in __slots__), and is an important technique for wrapper classes, where the wrapped object is declared in slots, so that the __dict__ has everything except the wrapped object.

Incorrect check result seen in scikit-hep/boost-histogram#914.

  • Command ruff check --select=ALL --isolated tmp.py
  • Ruff version: ruff 0.3.1
@charliermarsh charliermarsh added the bug Something isn't working label Mar 9, 2024
@charliermarsh
Copy link
Member

Thanks!

@charliermarsh
Copy link
Member

So is it correct to effectively turn off this check when __dict__ is present?

@henryiii
Copy link
Contributor Author

henryiii commented Mar 9, 2024

Basically. The condition is actually if a class has a __dict__, not if it has __slots__. Classes without __slots__ (anywhere in the inheritance chain) automatically get a __dict__. Classes with __slots__ (including in every parent) only get a dict if it's added manually in __slots__.

I assume you couldn't handle complex cases, but in the most common simple case of of a __slots__ having a string "__dict__", I assume you could treat that like a dict class?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working linter Related to the linter
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants