Desk Clarity

Everyday document & browser help

Dataclass Default Factory Is Not Callable: Pass a Constructor or Function

By ON Lab · Sources checked November 9, 2026

default_factory needs a zero-argument callable, not the list it should eventually create. Test that two instances get independent defaults, including any nested mutable data.

Reproduce the boundary in a disposable example

A dataclass field fails because default_factory was given a list value.

from dataclasses import dataclass, field
@dataclass
class Incorrect:
    tags: list = field(default_factory=["draft"])
try:
    Incorrect()
except TypeError:
    pass
else:
    raise AssertionError("expected noncallable factory failure")
@dataclass
class Record:
    tags: list = field(default_factory=lambda: ["draft"])
    notes: list = field(default_factory=list)
a, b = Record(), Record()
a.tags.append("checked")
a.notes.append("local note")
assert a.tags == ["draft", "checked"]
assert b.tags == ["draft"] and b.notes == []
assert a.tags is not b.tags
print("callable factory and independent defaults verified")

Read the result before changing application code

The bad declaration stores a list where a callable is expected; the failure appears when the generated initializer needs to invoke it. The good declaration creates the seeded list on demand. Passing list creates an empty list; passing list() has already created a value and therefore crosses the boundary too early.

Choose the behavior your caller needs

Use a named factory function when defaults need several steps or nested containers. Avoid a factory that simply returns one shared module-level list. When callers supply their own list explicitly, decide whether your record borrows it or copies it; default_factory does not automatically isolate caller-provided objects. Verify both default construction and explicit-argument construction in application tests.

Scope and limits

This covers the generated dataclass initializer’s default construction. It does not claim frozen dataclasses deeply freeze their list contents or that a factory validates field types.

Related: compare the adjacent data or execution boundary.

The embedded example was executed in an isolated local Python process on November 9, 2026. It is a reproducible boundary check, not a test of your full application.

Sources