From aa5a876051f9d84065a0da4932201627d60a9d5d Mon Sep 17 00:00:00 2001 From: Siyet Date: Tue, 16 Jun 2026 13:54:59 +0300 Subject: [PATCH] Document that omit_defaults ignores custom default_factory --- docs/structs.rst | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docs/structs.rst b/docs/structs.rst index b3199244..cf0f21b2 100644 --- a/docs/structs.rst +++ b/docs/structs.rst @@ -677,6 +677,23 @@ detection logic is as follows: ... return True ... return False +This detection never calls a ``default_factory``. A field configured with a +custom ``default_factory`` is only omitted when the factory is one of the +builtin collection constructors (``list``, ``dict``, ``set``, ``tuple``, or +``frozenset``). Any other callable (a user-defined function, a ``lambda``, or a +``Struct``/``dataclass``/``attrs`` type) is treated as opaque, so the field is +always encoded, even when the value it produces is empty. To omit an empty +collection default, configure the builtin constructor directly: + +.. code-block:: python + + >>> class Basket(msgspec.Struct, omit_defaults=True): + ... items: list[int] = msgspec.field(default_factory=list) + +The field annotation supplies the element type, so ``default_factory=list`` +still type checks. Specifying ``default=[]`` works too: ``msgspec`` doesn't +share mutable default values between instances. + .. _forbid-unknown-fields: