This rule raises an issue when a dataclass attribute is assigned a value without a type annotation, suggesting the developer likely intended an instance field but silently created a class variable instead.
The @dataclass decorator only processes attributes that have type annotations. Attributes without annotations are silently excluded
from dataclass processing and become regular class variables instead of instance attributes. This means:
\__init__ method\__repr__ or \__eq__Unannotated attributes are silently excluded from initialization, \__repr__, and \__eq__, making them invisible to the
dataclass contract. These bugs are difficult to trace because the class appears to work normally, but the affected attributes do not participate in
any of the generated methods.
Add type annotations to all attributes that should be dataclass fields.
If you intentionally want a class variable shared across all instances, annotate it with typing.ClassVar[T]. This is the idiomatic
Python way to declare class variables inside a dataclass. It makes the intent explicit and ensures the attribute is excluded from all generated
dataclass methods.
from dataclasses import dataclass
@dataclass
class Config:
timeout = 30 # Noncompliant: missing type annotation
retries = 3 # Noncompliant: missing type annotation
from dataclasses import dataclass
@dataclass
class Config:
timeout: int = 30
retries: int = 3
from dataclasses import dataclass
@dataclass
class Registry:
instance_count = 0 # Noncompliant: intended as a class variable, but not explicit
from dataclasses import dataclass
from typing import ClassVar
@dataclass
class Registry:
instance_count: ClassVar[int] = 0 # Explicit class variable, excluded from __init__