astral-sh / astral-sh/ruff

`object.__setattr__` triggering PLC2801 outside of dunder methods

Open
#11,636 3 comments 0 reactions 0 assignees View on GitHub
rule
Dominant language
Rust
Stars
49.6k
Forks
2.4k
Avg merge
1d 21h
Merged PRs (30d)
435

Description

Related to [false positive on PLC2801 "unnecessary dunder... for __setattr__" #9584](https://github.com/astral-sh/ruff/issues/9584)

`object.__setattr__` is the recommended way to set attributes on frozen dataclasses. This was addressed in #9584 but PLC2801 is triggering when `object.__setattr__` is in non-dunder methods.

See - https://play.ruff.rs/1a9602da-78ce-44c9-bbfe-b17b147da04b
```py
from dataclasses import dataclass, field

@dataclass(frozen=True)
class Foo:
a: int
b: int
c: int = field(init=False)

def __post_init__(self):
object.__setattr__(self, "c", self.a + self.b)

def foo(self):
object.__setattr__(self, "c", self.a - self.b) # <-------

def __str__(self):
object.__setattr__(self, "c", self.a * self.b)
```
```
14:9: PLC2801 Unnecessary dunder call to `__setattr__`. Mutate attribute directly or use setattr built-in function.
```
`ruff v0.4.6`

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the PLC2801 diagnostic with the linked Ruff Playground example, comparing object.__setattr__ in __post_init__, foo, and __str__. Trace the PLC2801 implementation and its existing handling from issue #9584. Done means the diagnostic no longer incorrectly flags the non-dunder method case while the intended checks remain covered.

Written by the indexing model from the issue text.

Assessment

Tech stack
python, rust
Domain
tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.