Defaults

August 10, 2026 ยท View on GitHub

A default is a recipe. It is certified when the schema compiles and rematerialized whenever a build or resolve omits its key.

DefaultRematerialization
int, float, str, bool, date, time, Nonepassed as is; immutable
Enum memberpassed as is; members are singletons
listfresh list; items rematerialized recursively
dataclass instancereconstructed through its constructor
default_factoryfactory called again

Recipes run once at struct_of/signature_of for certification and once per missing-key serving. A provided key never runs its recipe. The served value is validated each time, so an impure recipe that drifts outside its schema fails with a default path segment.

Certification uses the field's full contract, and no part of that contract reaches outside the schema and the value. A default under FileHint is validated like any other input, which here means its extension: the schema does not compile unless the default names an accepted kind of file. Whether that file exists and how large it is are not settled here and cannot be โ€” they are facts about the world, true only in the process and instant that asks, so they travel in the document and are applied by the wrapper where the value is actually used. A rematerialized path default is still exactly str; see atoms.md.

Defaults must be pure and deterministic: same recipe, equal result, no shared mutable state or observable side effects. The core cannot prove that promise. Mutating an externally held recipe object or the certified field.default violates the same rule from outside and remains the author's responsibility. The same promise covers the input: build validates it once and constructs from it, so the core watches neither concurrent mutation nor a __post_init__ that edits the input data. See build.md.

Instance reconstruction preserves equality, not internal alias topology. It runs __init__ and __post_init__ on every serving.

Python rejects a non-frozen dataclass instance used directly as a dataclass field default before pytypehint runs (ValueError: mutable default ... is not allowed). Use field(default_factory=...). Function defaults have no such Python restriction and may use an instance directly.

Calling a function directly still uses Python's shared defaults. Fresh function defaults apply only when data passes through signature_of(fn).resolve(...) or .build(...).