Using a mutable or stateful value as a default for a dataclass attribute is rarely what developers intend. The value is evaluated only once, when the class is defined, so every instance shares the same object.

Why is this an issue?

Default values for dataclass attributes are evaluated once when the class is defined, not each time an instance is created. This is a fundamental aspect of how Python evaluates default values.

When the default is produced by calling a function such as datetime.now() or uuid.uuid4(), or by a mutable container like [] or list(), the value is computed once and reused across every instance of the dataclass. Every instance therefore ends up with the same object.

@dataclass
class Event:
    timestamp: datetime = datetime.now()  # Noncompliant
    tags: list = []  # Noncompliant

event1 = Event()
event2 = Event()
event1.tags.append("x")
# event2.tags is also ["x"] — tags is the same list object.
# event1.timestamp and event2.timestamp are both the class-definition time.

In this example, event1 and event2 share the same tags list and the same timestamp.

What is the potential impact?

Using such defaults can cause reliability issues:

How to fix it

Use field(default_factory=…​) instead. The default_factory parameter accepts a callable, without parentheses, that is invoked each time a new instance is created, so each instance receives a fresh value.

The default_factory expects a callable with no arguments. If the function requires arguments, wrap it in a lambda or use functools.partial.

Code examples

Noncompliant code example

@dataclass
class Event:
    timestamp: datetime = datetime.now()  # Noncompliant
    event_id: uuid.UUID = uuid.uuid4()  # Noncompliant
    tags: list = []  # Noncompliant

Compliant solution

from dataclasses import dataclass, field

@dataclass
class Event:
    timestamp: datetime = field(default_factory=datetime.now)
    event_id: uuid.UUID = field(default_factory=uuid.uuid4)
    tags: list = field(default_factory=list)

Resources

Documentation

Related rules