Closed kkg-else42 closed 3 months ago
So this is how it works. Cattrs binds types to functions (hooks). The defaults are different when structuring and unstructuring because data is treated differently when entering and exiting your system.
Every type needs a hook. If a hook does not exist, the fallback hook factory gets called, and by default that will cause an exception to be raised.
You may be wondering why the fallback hook doesn't do an isinstance
check before raising, and the answer is that there are a lot of edge cases where that wouldn't work (especially with fancy types, protocols, newtypes, type aliases...), and a whitelist approach is easier to understand.
That said, you can assume responsibility for this yourself like this:
def structure_hook_factory(type):
def hook(val, _):
if not isinstance(val, type):
raise ValueError("Wrong type")
return val
return hook
c = Converter(structure_fallback_factory=structure_hook_factory)
print(c.structure({"dt": datetime.datetime(2024, 3, 26, 16, 40, 30)}, A))
>>> A(dt=datetime.datetime(2024, 3, 26, 16, 40, 30))
So it's a design choice!
Hey there!
In the following situation it is necessary to use a structure hook for the handling of datetime. And I know how to do that. But I would be interested to know why it is necessary.