NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #544 most downloaded on PyPI
Composable complex class support for attrs and dataclasses.
Last release 8 days ago
26 Sep 2026
Release timing varies
gaps range from 2 weeks to 9 months
Nearly every release is documented
notes for 36 of 37 stable releases
4 versions withdrawn
withdrawn after publishing
9 years old
44 releases · first in 2017
Fix heterogeneous tuples and NamedTuple s with a member type containing a quote in its repr , like tuple[Literal["a"], int] , crashing structuring cod
NamedTuples with a member type containing a quote in its repr, like tuple[Literal["a"], int], crashing structuring code generation with SyntaxError; the index note is now embedded with repr. (#777)transform_error listing the extra keys of a ForbiddenExtraKeysError in set iteration order, which made the message differ between runs; the keys are now sorted, like the error's own __str__ already sorts them. (#776)Full Changelog: v26.2.0...v26.2.1
NamedTuples with a member type containing a quote in its repr, like tuple[Literal["a"], int], crashing structuring code generation with SyntaxError; the index note is now embedded with repr.
(#777)transform_error <cattrs.transform_error> listing the extra keys of a ForbiddenExtraKeysError in set iteration order, which made the message differ between runs; the keys are now sorted, like the error's own __str__ already sorts them.
(#776)One column per quarter.
Fix the msgpack and cbor2 converters unstructuring naive datetimes as local time, which made the serialized value depend on the timezone of the machin
msgpack and cbor2 converters unstructuring naive datetimes as local time, which made the serialized value depend on the timezone of the machine doing the unstructuring; naive datetimes are now assumed to be UTC, matching what the structure hooks already read back. (#774 #775)override(rename=...) targets containing a quote (or other characters not safe in a bare string literal) crashing code generation with SyntaxError; the rename key is now embedded with repr. (#771)Counter keys not being unstructured with the key type's own hook; the single-type-arg branch passed the whole type-args tuple to the key hook lookup instead of the key type. (#768)create_default_dis_func (aka create_uniq_field_dis_func) failing to disambiguate valid unions depending on the order of the member classes; unique fields are now resolved iteratively to a fixpoint. (#230 #765)annotationlib.ForwardRef. (#740 #741)Converter now uses specialized hook factories to generate hooks for tuples, increasing speed. (#737)AttributeError in cattrs internals that could be triggered by using the include_subclasses strategy in a structure_hook_factory (#721, #722)CattrsError exception type: all exceptions raised by cattrs inherit from this.Exception. (#728)detailed_validation parameter being passed under the wrong name in namedtuple_dict_structure_factory, causing it to be silently ignored. (#723)cbor2 installed. (#748)BaseConverter.register_structure_hook_factory and BaseConverter.register_unstructure_hook_factory now properly return the factory when used as decorators. (#724)msgspec preconf converter now properly handles recursive classes on Python 3.14+. (#757)Full Changelog: v26.1.0...v26.2.0
Add the tomllib preconf converter. See here for details.
tomllib preconf converter. See here for details. (#716)Annotated[T, override()] on fields. See here for more details. (#717)omit_if_default is true and an attrs converter is specified. (#696)_value_ type hint to structure and unstructure enums if present. (#699)tomlkit preconf converter now properly handles native date objects when structuring. (#707 #708)tomlkit preconf converter now passes date objects directly to tomlkit for unstructuring. (#707 #708)cattrs.strategies.include_subclasses when used with cattrs.strategies.configure_tagged_union and classes using diamond inheritance. (#685 #713)cattrs.strategies.configure_tagged_union when used with recursive type aliases. (#678 #714)Full Changelog: v25.3.0...v26.1.0
Potentially breaking : Abstract sets are now structured into frozensets. This allows hashability, better immutability and is more consistent with the
collections.abc.Set type.BaseConverter. (#684)cattrs.strategies.include_subclasses now works with generic parent classes and the tagged union strategy. (#683)Full Changelog: v25.2.0...v25.3.0
Potentially breaking : Sequences are now structured into tuples. This allows hashability, better immutability and is more consistent with the collecti
collections.abc.Sequence type. See Migrations for steps to restore legacy behavior. (#663)use_alias parameter to cattrs.Converter.cattrs.gen.make_dict_unstructure_fn_from_attrs, cattrs.gen.make_dict_unstructure_fn,cattrs.gen.make_dict_structure_fn_from_attrs, cattrs.gen.make_dict_structure_fncattrs.gen.typeddicts.make_dict_structure_fn will use the value for the use_alias parameter from the given converter by default now. If you're using these functions directly, the old behavior can be restored by passing in the desired value directly. (#596 #660)cattrs.errors.StructureHandlerNotFoundError and cattrs.errors.ForbiddenExtraKeysErrorBaseException.args in super() and hence make them pickable. (#666)unstructure_strat=AS_DICT (the default).unstructure_strat=AS_TUPLE converters. (#673)uv and just in lieu of PDM, tox and Make. See the Contributing section for new workflow instructions. (#671)Full Changelog: v25.1.1...v25.2.0
Fixed AttributeError: no attribute '__parameters__' while structuring attrs classes that inherit from parametrized generic aliases from collections.ab
Potentially breaking : The converters raise StructureHandlerNotFoundError more eagerly (on hook creation, instead of on hook use). This helps surfacin
StructureHandlerNotFoundError more eagerly (on hook creation, instead of on hook use). This helps surfacing problems with missing hooks sooner. See Migrations for steps to restore legacy behavior.typing.Self is now supported in attrs classes, dataclasses, TypedDicts and the dict NamedTuple factories. See typing.Self for details.BaseConverter.register_structure_hook and BaseConverter.register_unstructure_hook. Previously, they required the use of BaseConverter.register_structure_hook_func (which is still supported).cattrs.cols.mapping_unstructure_factory through cattrs.cols.defaultdicts are now supported by default, andcattrs.cols.is_defaultdict and cattrs.cols.defaultdict_structure_factory are exposed through cattrs.cols.Converter.copy and BaseConverter.copy are correctly annotated as returning Self.int and str enums, leaving them to the underlying libraries to handle with greater efficiency.ClassValidationError.cattrs.strategies.include_subclasses now properly works with generic parent classes.cattrs.gen.MappingStructureFn with cattrs.SimpleStructureHook.Converter.__init__.unstruct_collection_overrides from Callable to Mapping[type, UnstructureHook]StructureHandlerNotFoundError more eagerly (on hook creation, instead of on hook use).
This helps surfacing problems with missing hooks sooner.
See Migrations for steps to restore legacy behavior.
(#577)typing.Self is now supported in attrs classes, dataclasses, TypedDicts and the dict NamedTuple factories.
See typing.Self for details.
(#299 #627)BaseConverter.register_structure_hook and {meth}BaseConverter.register_unstructure_hook.
Previously, they required the use of {meth}BaseConverter.register_structure_hook_func (which is still supported).
(#647)cattrs.cols.mapping_unstructure_factory through {mod}cattrs.cols.defaultdicts are now supported by default, and
{func}cattrs.cols.is_defaultdict and {func}cattrs.cols.defaultdict_structure_factory are exposed through {mod}cattrs.cols.
(#519 #588)Converter.copy and {meth}BaseConverter.copy are correctly annotated as returning Self.
(#644)int and str enums,
leaving them to the underlying libraries to handle with greater efficiency.
(#598)msgspec JSON preconf converter <cattrs.preconf.msgspec.MsgspecJsonConverter> now handles dataclasses with private attributes more efficiently.
(#624)ClassValidationError.
(#615 #616)cattrs.strategies.include_subclasses now properly works with generic parent classes.
(#649)cattrs.gen.MappingStructureFn with {class}cattrs.SimpleStructureHook.Converter.__init__.unstruct_collection_overrides from Callable to Mapping[type, UnstructureHook]
(#594).Fix structuring of keyword-only dataclass fields when not using detailed validation. ( #637 #638 )
Fix BaseConverter.register_structure_hook and BaseConverter.register_unstructure_hook type hints. ( #581 #582 )
Fix BaseConverter.register_structure_hook_factory and BaseConverter.register_unstructure_hook_factory type hints. (#578 #579)
Potentially breaking: Unstructuring hooks for typing.Any are consistent now: values are unstructured using their runtime type. Previously this behavio
typing.Any are consistent now: values are unstructured using their runtime type.
Previously this behavior was underspecified and inconsistent, but followed this rule in the majority of cases.
Reverting old behavior is very dependent on the actual case; ask on the issue tracker if in doubt.
(#473)cattrs.gen.make_dict_structure_fn will use the value for the prefer_attrib_converters parameter from the given converter by default now.
If you're using this function directly, the old behavior can be restored by passing in the desired values explicitly.
(#527 #528)BaseConverter.get_structure_hook and BaseConverter.get_unstructure_hook methods.
(#432 #472)BaseConverter.register_structure_hook, BaseConverter.register_unstructure_hook,
BaseConverter.register_unstructure_hook_factory and BaseConverter.register_structure_hook_factory
can now be used as decorators and have gained new features.
See here and here for more details.
(#487)cattrs.cols module for better collection customizations.
(#504 #540)cattrs.cols.is_mapping predicate function to also cover virtual subclasses of abc.Mapping.
This enables map classes from libraries such as immutables or sortedcontainers to structure out-of-the-box.
(#555 #556)preconf converter <cattrs.preconf.msgspec>.
Only JSON is supported for now, with other formats supported by msgspec to come later.
(#481)TypeVars with defaults.
(#512)typing.NamedTuple).
(#425 #491)include_subclasses strategy now fetches the member hooks from the converter (making use of converter defaults) if overrides are not provided, instead of generating new hooks with no overrides.
(#429 #472)make_converter factories are now correctly typed.
(#481)orjson preconf converter now passes through dates and datetimes to orjson while unstructuring, greatly improving speed.
(#463)cattrs.gen generators now attach metadata to the generated functions, making them introspectable.
(#472)cattrs.gen now handle recursive classes better.
(#540)forbid_extra_keys is set.
(#533 #534)Annotated and NotRequired in TypedDicts.
(#450)typing_extensions.Literal is now automatically structured, just like typing.Literal.
(#460 #467)typing_extensions.Any is now supported and handled like typing.Any.
(#488 #490)Optional types can now be consistently customized using register_structure_hook and register_unstructure_hook.
(#529 #530)include_subclasses and tagged_union strategies more lenient.
(#431)Fix a regression when unstructuring dictionary values typed as Any . ( #453 #462 )
Fix a regression when unstructuring Any | None.
Any | None.
(#453)Fix unnecessary typing_extensions import on Python 3.11. (#446 #447)
Welcome to _cattrs_ 23.2.0! Thanks to all our wonderful contributors, this release happens to have the largest changelog so far.
Welcome to cattrs 23.2.0! Thanks to all our wonderful contributors, this release happens to have the largest changelog so far.
Here are some of the noteworthy additions, see below for the entire changelog.
Courtesy of the union passthrough strategy, the following class (and others like it, this is just a complex example) will work out-of-the-box on any preconf converter:
@define
class MyClass:
my_field: str | Literal[1] | MyOtherClass
The strategy has been preapplied to all preconf converters, but it can be manually applied to any converter.
When structuring a union of attrs classes, cattrs will default to the default union strategy.
This strategy works by finding required unique fields in the given classes. It has been enhanced with support for matching on fields annotated as Literals.
from typing import Literal
@define
class ClassA:
field_one: Literal["one"]
@define
class ClassB:
field_one: Literal["two"] = "two"
cattrs defaults to having un/structuring hooks separate from the models. With the use class methods strategy, you are free to defy this design decision and configure a converter to look for hooks on the models themselves.
init=False by default. This change is potentially breaking for unstructuring.
See here for instructions on how to restore the old behavior.
(#40 #395)cattrs.gen.make_dict_structure_fn and cattrs.gen.typeddicts.make_dict_structure_fn will use the values for the detailed_validation and forbid_extra_keys parameters from the given converter by default now.
If you're using these functions directly, the old behavior can be restored by passing in the desired values directly.
(#410 #411)typing.Literal to help guide structuring.
See here for instructions on how to restore the old behavior.
(#391)union passthrough strategy, enabling much richer union handling for preconfigured converters. Learn more here.use_class_methods strategy. Learn more here.
(#405)omit parameter of cattrs.override is now of type bool | None (from bool).
None is the new default and means to apply default cattrs handling to the attribute, which is to omit the attribute if it's marked as init=False, and keep it otherwise.date to preconfigured converters.
(#420)datetime.dates to the PyYAML preconfigured converter.
(#393)format_exception() parameter working for recursive calls to transform_error().
(#389)Optional (unions of one type and None).
(#380 #381)format_exception and transform_error type annotations.cattrs._compat.is_typeddict. The implementation is now simpler, and relies on fewer private implementation details from typing and typing_extensions.
(#384)cattrs.preconf.orjson.OrjsonConverter.loads type definition for the preconf orjson converter.
(#400)AttributeValidationNote and IterableValidationNote are now picklable.
(#408)Final lists.
(#412)Annotated types.
(#418)forbid_extra_keys.
(#402 #443)htmlview and htmllive targets. (#442)main branch commits are automatically deployed to Test PyPI.Improve typing_extensions version bound.
typing_extensions version bound. (#372)Add typing_extensions as a direct dependency on 3.10. (#369 #370)
Introduce the `tagged_union` strategy. (#318 #317)
tagged_union strategy.
(#318 #317)cattrs.transform_error helper function for formatting validation exceptions. (258 342)typing.TypedDict and typing_extensions.TypedDict.
(#296 #364)typing.Final.
(#340 #349)override.struct_hook and override.unstruct_hook. Learn more here.
(#326)<>) and pipe symbols (|) in the name.
(#319 #327)pathlib.Path is now supported by default.
(#81)cbor2 serialization library to the cattrs.preconf package.cattrs.preconf third-party libraries. (#337)unstruct_collection_overrides in make_converter.
(#350 #353)include_subclasses strategy.
(#312)typing_extensions.Annotated when the python version is less than 3.9. (#366)deque.
(#355)Nothing published for this version
The GenConverter name is still available for backwards compatibility, but is deprecated. If you were depending on functionality specific to the old Co…
cattrs.Converter has been renamed to cattrs.BaseConverter, and cattrs.GenConverter to cattrs.Converter.
The GenConverter name is still available for backwards compatibility, but is deprecated.
If you were depending on functionality specific to the old Converter, change your import to from cattrs import BaseConverter.cattrs.Converter.
(#255 #94 #297)cattrs.Converter and cattrs.BaseConverter can now copy themselves using the copy method.
(#284)kw_only fields on attrs classes into/from dictionaries.
(#247)detailed_validation flag to mapping and counter structuring generators.typing.Set applying too broadly when used with the GenConverter.unstruct_collection_overrides parameter on Python versions below 3.9. Switch to typing.AbstractSet on those versions to restore the old behavior.
(#264)Converter.register_structure_hook_factory and cattrs.gen.make_dict_unstructure_fn type annotations.
(#281)cattr.errors namespace. Note that it is deprecated, just use cattrs.errors.
(#252)exceptiongroup>=1.0.0rc4.
(#303)_cattrs_ now uses the CalVer versioning convention.
detailed_validation=False.typing.List s on Pythons lower than 3.9.
(#209)list/dict/... on Pythons lower than 3.9.
(#218)typing.Tuple on Pythons lower than 3.9.
(#218)AttributeError of an missing __parameters__ attribute. This could happen
when inheriting certain generic classes – for example typing.* classes are affected.
(#217)enum.Enum instances in typing.Literal types.
(#231)list.
(#226)forbid_extra_keys raise custom ForbiddenExtraKeyError instead of generic Exception.
(#225)loads and dumps directly. See an example here.The cattr package is never going away, nor is it technically deprecated. New functionality will be added only to the cattrs package, but there is no n…
In this release, _cattrs_ introduces the {mod}`cattrs` package as the main entry point into the library, replacing the `cattr` package.
The `cattr` package is never going away, nor is it technically deprecated.
New functionality will be added only to the `cattrs` package, but there is no need to replace your current imports.
This change mirrors [a similar change in _attrs_](https://www.attrs.org/en/stable/names.html).
cattrs.gen.make_dict_unstructure_fn omit_if_default parameter to _cattrs_omit_if_default, for consistency. The omit_if_default parameters to {class}GenConverter and {func}override are unchanged.cattrs package mirroring the existing cattr package. Both package names may be used as desired, and the cattr package isn't going away.Python 3.10 support, including support for the new union syntax (A | B vs Union[A, B]).
A | B vs Union[A, B]).GenConverter can now properly structure generic classes with generic collection fields.
(#149)omit=True now also affects generated structuring functions.
(#166)cattr.gen.{make_dict_structure_fn, make_dict_unstructure_fn} now resolve type annotations automatically when PEP 563 is used.
(#169)_cattrs_forbid_extra_keys=True.
(#190)Fix GenConverter mapping structuring for unannotated dicts on Python 3.8.
GenConverter mapping structuring for unannotated dicts on Python 3.8.
(#151)linecache cache, which enables more informative stack traces when un/structuring errors happen using the GenConverter. This behavior can optionally be disabled to save memory.prefer_attrib_converters=True on Converter or GenConverter.
(#138)cattr.override now supports the omit parameter, which makes cattrs skip the atribute entirely when unstructuring.cattr.preconf.bson module is now tested against the bson module bundled with the pymongo package, because that package is much more popular than the standalone PyPI bson package.Literal s are not supported on Python 3.9.0 (supported on 3.9.1 and later), so we skip importing them there.
Literal s are not supported on Python 3.9.0 (supported on 3.9.1 and later), so we skip importing them there.
(#150)cattr.global_converter (which provides cattr.unstructure, cattr.structure etc.) is now an instance of cattr.GenConverter.
cattr.global_converter (which provides cattr.unstructure, cattr.structure etc.) is now an instance of cattr.GenConverter.Literal s are now supported and validated when structuring.GenConverter mapping structuring for unannotated dicts.
(#148)GenConverter mapping structuring is now ~25% faster, and unstructuring heterogenous tuples is significantly faster.
GenConverter mapping structuring is now ~25% faster, and unstructuring heterogenous tuples is significantly faster.cattr.preconf. This package contains modules for making converters for particular serialization libraries. We currently support the standard library json, and third-party ujson, orjson, msgpack, bson, pyyaml and tomlkit libraries.Fix an issue with GenConverter unstructuring _attrs_ classes and dataclasses with generic fields.
GenConverter unstructuring attrs classes and dataclasses with generic fields.
(#65)GenConverter has support for easy overriding of collection unstructuring types (for example, unstructure all sets to lists) through its unstruct_collection_overrides argument.
(#137)GenConverter is significantly faster.GenConverter supports strict handling of unexpected dictionary keys through its forbid_extra_keys argument.
(#142)These should be used on 3.9+ instead of their typing alternatives, which are deprecated.
GenConverter un/structuring hooks when a function hook is registered after the converter has already been used.collections.abc.{Sequence, MutableSequence, Set, MutableSet}. These should be used on 3.9+ instead of their typing alternatives, which are deprecated.
(#128)GenConverter will unstructure iterables (list[T], tuple[T, ...], set[T]) using their type argument instead of the runtime class if its elements, if possible. These unstructuring operations are up to 40% faster.
(#129)Converter and GenConverter initializer type annotations.
(#131)typing.Annotated on Python 3.9+. cattrs will use the first annotation present. cattrs specific annotations may be added in the future.
(#127)_cattrs_ now has a benchmark suite to help make and keep cattrs the fastest it can be. The instructions on using it can be found under the Benchmarkin
attr.resolve_types on attrs classes when registering un/structuring hooks.GenConverter structuring and unstructuring of attrs classes is significantly faster.converter.unstructure now supports an optional parameter, unstructure_as, which can be used to unstructure something as a different type. Useful for u
converter.unstructure now supports an optional parameter, unstructure_as, which can be used to unstructure something as a different type. Useful for unions.GenConverter behavior with inheritance hierarchies of attrs classes.
([#117](https://github.com/python-attrs/cattrs/pull/117 #116)GenConverter.un/structure_attrs_fromdict into GenConverter.gen_un/structure_attrs_fromdict to allow calling back to Converter.un/structure_attrs_fromdict without sideeffects.
(#118)The default disambiguator will not consider non-required fields any more.
Add metadata for supported Python versions.
Python 2, 3.5 and 3.6 support removal. If you need it, use a version below 1.1.0.
list[int] vs typing.List[int]).omit_if_default and rename). See the cattr.gen module.cattr.GenConverter, that automatically generates specialized hooks for attrs classes. This converter will become the default in the future.attr.resolve_types._attrs_ classes with private attributes can now be structured by default.
Nothing published for this version
Nothing published for this version
- Python 3.7 support.
The disambiguation function generator now supports unions of _attrs_ classes and NoneType.
- Distribution fix.
Nothing published for this version
Removed the undocumented Converter.unstruct_strat property setter.
Converter.unstruct_strat property setter.Converter.structure_attrs instance field.structure(unstructure(obj)) roundtrip
is now up to 2 times faster.- Packaging fixes.
structure/unstructure now supports using functions as well as classes for deciding the appropriate function.
Converter.register_structure_hook_func, to register a function instead of a class for determining handler func.Converter.register_unstructure_hook_func, to register a function instead of a class for determining handler func.Optional attributes can no longer be structured if they are missing in the input.cattr.typed removed since the functionality is now present in attrs itself.
Replace instances of cattr.typed(type) with attr.ib(type=type).Your coding agent can read these notes before it upgrades. Set up the MCP server →