Add support for default_factory
on Struct
types
#274
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR does a few things:
msgspec.field
function, which returns an opaque object used for configuring fields. So far this only exposesdefault
anddefault_factory
, both of which match thedataclasses
kwargs of the same name.msgspec.Struct
types, through use of the newdefault_factory
setting (fixes Support default factories for Struct types #259).Example:
Breaking Change: mutable default values in structs are now handled differently
This also changes how mutable default values are handled. Previously msgspec's semantics were that a default value for a field would be deepcopied on
__init__
if that field wasn't provided (the implementation would avoid a deepcopy for most common types, but semantically this was the same). This proved problematic in the face of custom types, led to some unnecessary slowdowns, and didn't match the behavior of other similar libraries likedataclasses
orattrs
. Since we now can support arbitrarily complex default values through thedefault_factory
function, we drop the olddeepcopy
behavior.A default value on a
Struct
now has the following rules:default_factory
instead.[]
,{}
,set()
,bytearray()
) are accepted as default values. These are treated as syntactic sugar, and are automatically converted to the equivalentdefault_factory
notation ([]
->field(default_factory=list)
).default_factory
instead.Since most mutable default values are empty collections, I don't expect this breaking change to affect most users. To reiterate, the following type definition is still valid:
while this one will error, and should use a
default_factory
instead:Todo: