Closed aha79 closed 8 months ago
I think the culprit lies here: https://github.com/python-attrs/cattrs/blob/c447dfe4de2978ef1bb2974b53562e413fe28a1a/src/cattrs/strategies/_subclasses.py#L98
No additional arguments are passed as for instance in the 'gen_xx' function:
However, I am not sure if it is a good idea at all to call 'makedict(un)structure_fn' directly there (even when the missing arguments are added), as it will also prevent user-defined hooks from working.
You're right, I can reproduce the issue. Took me a while to understand what's going on. Two separate issues here: existing hooks aren't honored, and converter.omit_if_default
isn't honored when new hooks are generated.
We could make the strategy fish out hooks out of the converter instead of generating them; that way existing hooks and converter flags would be automatically honored. The problem is the strategy was written to take overrides, implying it would generate hooks for you with these overrides, so this would be a backwards-incompatible API change. So we need to be careful here.
We could make it so the hooks are not generated if there are no overrides; I think this would work but it just complicates the strategy with a separate behavior path. Maybe it's ok?
The simplest change would be to just let the strategy pass converter.omit_if_default
to gen_unstructure_hook
. This would solve your particular issue.
Personally I like the idea of using the existing generator hook if there are no overrides and regenerate the hook if there are overrides. It doesnt seem very unclean, but I do not know if there are any not yet seen pitfalls.
But after looking at the code and thinking about what you wrote, I see another problem:
As a solution maybe one can augment 'gen_unstructure_attrs_fromdict' and 'gen_structure_attrs_fromdict' to accept another 'overrides ' as arguments and then call these functions from 'include_subclasses' if there are call level overrides for re-generation (and use existing hooks if there are no overrides). Just an idea
Yeah I'm warming up to the idea of fishing the hook out if no overrides. Maybe that's the way to go.
The type_overrides are mostly used for customizing collections so I don't think those will be problematic, unless I'm misunderstanding your concern.
Your second bullet is valid, and would also be fixed by fishing the hook out if no overrides. You can apply your overrides prior to applying the strategy and let the strat fish em out.
Regarding the typeoverrides: I was thinking of renaming fields. Sometimes there is no way around, e.g. if the dict key is a python reserved keyword ('class', 'if'), and the dataclass has to have altered field names ('class', 'if_). And that should also work if the dataclass is in a union.
I've changed it so the strategy uses the converter to get the base hooks when no overrides are provided, so converter-level customizations should propagate now.
Description
The tagged union disambiguation seems to ignore
omit_if_default=True
What I Did
Maybe this is related https://github.com/python-attrs/cattrs/issues/402