Jump to content

Connect Leeroopedia MCP: Equip your AI agents to search best practices, build plans, verify code, diagnose failures, and look up hyperparameter defaults.

Heuristic:Dagster io Dagster Record Over Dataclass

From Leeroopedia





Knowledge Sources
Domains Code_Style, Data_Structures
Last Updated 2026-02-10 12:00 GMT

Overview

Mandatory convention to use @record instead of @dataclass for all data structures in the Dagster codebase.

Description

The Dagster codebase uses a custom @record decorator (from dagster_shared.record) as its sole data structure pattern, replacing Python's @dataclass. Records are immutable by default, support structural equality, and provide a consistent with_* method pattern for creating modified copies. This is a strict coding convention that is enforced across the entire codebase.

Usage

Use this heuristic whenever creating new data structures in the Dagster codebase. If you see a @dataclass in new code, it should be converted to @record. The convention also applies when modifying existing data structures or reviewing pull requests.

The Insight (Rule of Thumb)

  • Action: Use @record from dagster_shared.record for ALL data structures. NEVER use @dataclass.
  • Value: Provides immutability by default, structural equality, and consistent mutation patterns across the codebase.
  • Trade-off: Slight learning curve for contributors unfamiliar with the custom @record API. Cannot use dataclass-specific features like __post_init__.
  • Mutation pattern: Use with_* methods for creating modified copies (e.g., result.with_error(err)).

Reasoning

The @record decorator was introduced to address several issues with @dataclass:

  1. Immutability by default: Dataclasses are mutable by default (frozen=False). Dagster needs immutable data structures for safe concurrent access and caching.
  2. Consistent API: The with_* naming convention provides a clear, discoverable pattern for creating modified copies without mutating the original.
  3. Serialization: Records integrate with Dagster's serialization framework (whitelist_for_serdes) more cleanly than dataclasses.
  4. NamedTuple migration: The codebase historically used NamedTuple extensively. @record provides a modern replacement that maintains immutability guarantees.

Code Evidence

From .claude/coding_conventions.md:

# CORRECT - Use @record
from dagster_shared.record import record

@record
class AssetConditionSnapshot:
    condition_type: str
    description: str
    unique_id: str

# Create modified copies with with_* methods
snapshot = AssetConditionSnapshot(
    condition_type="eager",
    description="...",
    unique_id="abc123"
)
# WRONG - Do NOT use @dataclass
from dataclasses import dataclass

@dataclass
class AssetConditionSnapshot:  # This will be rejected in code review
    condition_type: str
    description: str
    unique_id: str

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment