-
-
Notifications
You must be signed in to change notification settings - Fork 114
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dynamic strategy for subclasses #434
Comments
Howdy, so I gather the problem is this: from attrs import define
from cattrs import Converter
from cattrs.strategies import include_subclasses
c = Converter()
@define
class Base:
a: int
include_subclasses(Base, c)
@define
class Child(Base):
b: int
print(c.structure({"a": 1, "b": 2}, Base)) # Base(a=1) The fact Here's a general cattrs trick that we can use: we'll register a structure hook factory for the from typing import Callable
from attrs import define
from cattrs import Converter
from cattrs.strategies import include_subclasses
c = Converter()
@define
class Base:
a: int
def make_include_subclasses_hooks(_: type) -> Callable:
include_subclasses(Base, c)
return c._structure_func.dispatch(Base)
c.register_structure_hook_factory(lambda t: t is Base, make_include_subclasses_hooks)
@define
class Child(Base):
b: int
print(c.structure({"a": 1, "b": 2}, Base)) # Child(a=1, b=2) Also don't be alarmed by Let me know if this solves your issue. |
Hi @Tinche, Thanks a lot for your quick help! I think this could actually solve my problem, but the scenario is a bit more complicated. In particular, I have an intermediate abstract class and also need a union strategy. Let me first share an extended example and then give the context and ask my questions below. Code
The code above will run just fine, but as you can see, things are getting complicated :D Question 1The fact that the Question 2In my code, I not only need to (un-)structure as base class, but also as the intermediate class. The only way I saw to achieve this is register additional factories and generalize the logic so that the factories themselves can be created via factories. Again, seems quite complicated. Is this how you would do it? Next StepsEven with the logic above, I'm still struggling to apply the new |
Description
(copied from #312)
Hi guys 👋 It's great that the subclass feature is finally coming in the next release. I've been hoping for it for quite a while, it allows me to get rid of some manual workarounds 👍
I do have one question, though. I'm currently playing around with it and trying to incorporate it into our codebase. In most places, it worked out-of-the-box, but I encountered problems with one of my class hierarchies. When I looked a bit deeper, I suddenly understood what is the problem: the subclass tree is constructed during the call of include_subclasses and not at the time of structuring. This differs from my manual workaround, in which the lookup was done inside the hook itself. The logic was as roughly as follows:
where get_subclasses builds the subclass tree similar to your code.
The fact that the classes are collected in include_subclasses causes a problem to me in that no subclasses can be added later on. Do you see any solution to this problem?
I can imagine at least two use cases where a delayed lookup would be necessary:
Maybe I'm even misusing the feature, but then I'd be also happy about getting your input :D
The text was updated successfully, but these errors were encountered: