astral-sh / ruff

An extremely fast Python linter and code formatter, written in Rust.
https://docs.astral.sh/ruff
MIT License
33.1k stars 1.11k forks source link

`RUF009` handles `attrs` dataclasses with `auto_attribs = False` incorrectly #14519

Closed InSyncWithFoo closed 2 days ago

InSyncWithFoo commented 4 days ago

From #14327:

Note that RUF009 can be a bit misleading when auto_attribs=False (or with older attr.s codebases):

import attrs

@attrs.define(auto_attribs=False)
class X:
    a_field: int = attrs.field(default=42)
    not_a_field: list = (lambda: [])()
#                       ^^^^^^^^^^^^^^ RUF009 Do not perform function call in dataclass defaults

Without auto_attribs, not_a_field can't possibly be a dataclass field. In this example, it's an incorrectly typed class variable. Fixing the typing error also fixes the RUF009 warning:

@attrs.define(auto_attribs=False)
class X:
    a_field: int = attrs.field(default=42)
    not_a_field: typing.ClassVar[list] = (lambda: [])()

This is an issue though when using attrs.field wrappers:

def my_field():
    return attrs.field(default=42, metadata={"my_metadata": 42})

@attrs.define(auto_attribs=False)
class X:
    a_field: int = my_field()
#                  ^^^^^^^^^^ RUF009 Do not perform function call `my_field` in dataclass defaults

— @pwuertz