Closed
Description
Hi cattrs team,
I encountered a seemingly quite surprising feature of cattrs, namely that the ordering of registered hooks could affect the serialization outcome of nested attrs or dataclasses.
See the two cases below.
I guess it would be not too surprising if one understands that make_dict_unstructure_fn
relies on context information (what has been registered and what is in namespace, perhaps).
But I think this could be confusing behavior, and more information could be added to the documentation. Or perhaps, some different mechanism should be implemented to make the ordering does not matter.
cattrs version: 24.1.2
python version: 3.9.6
from __future__ import annotations
from cattrs.preconf.orjson import make_converter
import attrs
from cattrs.gen import make_dict_unstructure_fn
@attrs.define
class AModel:
a: int
@attrs.define
class TopModel:
top: AModel
converter = make_converter()
obj = TopModel(top=AModel(1))
converter.register_unstructure_hook(AModel, lambda obj: "A")
converter.register_unstructure_hook(
TopModel, make_dict_unstructure_fn(TopModel, converter)
)
se = converter.unstructure(obj, TopModel) #output :{'top': 'A'}
If the order of hooks is reversed
converter.register_unstructure_hook(
TopModel, make_dict_unstructure_fn(TopModel, converter)
)
converter.register_unstructure_hook(AModel, lambda obj: "A")
se = converter.unstructure(obj, TopModel) #output: {'top': {'a': 1}}