You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hi @Tinche, I am currently working on several projects where I need to (un)structure objects of subclasses of a common base class. Digging through the documentation and also some issues here on Github, I eventually found your example how this can be done with the current version of cattrs. However, I think I have found two problems (bugs? unsupported features?) with the approach and would love to hear your opinion.
But before I go into the details, a quick question upfront: Is this going to remain the "recommended" approach to unstructure objects from a class hierarchy? I am asking because I also saw #312 which seems about to be merged but I am not entirely sure how/if it's going to replace your described method.
So here are now the two issues I noticed:
With the version described above, your example no longer seems to work. In order to get it running, one now needs to explicitly set slotted=False. I guess this is probably due to due the changes defaults (see also Weird output while structuring unions with custom disambiguation function #267)? On the other hand, I wonder why your example then originally worked because it already uses define instead of attr.s?
Still, I struggled a lot to get it running in my own code until I finally found the problem: The approach crashes when using from __future__ import annotations and throws the following exception:
Traceback (most recent call last):
File "/usr/local/Caskroom/mambaforge/base/envs/baybe/lib/python3.8/site-packages/cattrs/converters.py", line 461, in _structure_attribute
return self._structure_func.dispatch(type_)(value, type_)
File "/usr/local/Caskroom/mambaforge/base/envs/baybe/lib/python3.8/site-packages/cattrs/converters.py", line 377, in _structure_error
raise StructureHandlerNotFoundError(msg, type_=cl)
cattrs.errors.StructureHandlerNotFoundError: Unsupported type: 'int'. Register a structure hook for it.
Is the second issue related to #215 or is this a bug?
The text was updated successfully, but these errors were encountered:
Thanks for your reply! The code example is really just your code + the future import:
from __future__ import annotations
from attr import define
from cattr import GenConverter
c = GenConverter()
@define
class Base:
a: int
@define
class SubOne(Base):
b: int
@define
class SubTwo(Base):
c: int
def unstructure_base(b):
return {"_type": b.__class__.__name__, **c.unstructure_attrs_asdict(b)}
c.register_unstructure_hook(Base, unstructure_base)
print(c.unstructure(SubOne(1, 2)))
def structure_base(val, _):
sub_name = val.pop("_type")
for klass in Base.__subclasses__():
if klass.__name__ == sub_name:
return c.structure_attrs_fromdict(val, klass)
return c.structure_attrs_fromdict(val, Base)
c.register_structure_hook(Base, structure_base)
print(c.structure(c.unstructure(SubOne(1, 2)), Base))
print(c.structure(c.unstructure(SubTwo(1, 2)), Base))
print(c.structure(c.unstructure(Base(1)), Base))
However, I've now also tested with python 3.11 and there everything works as expected! So the issue seems really related to how the future imports are handled in older python versions 🤔 Nonetheless, it might be worth mentioning this somewhere in the docs once one of us figures out the source of the problem...
Description
Hi @Tinche, I am currently working on several projects where I need to (un)structure objects of subclasses of a common base class. Digging through the documentation and also some issues here on Github, I eventually found your example how this can be done with the current version of cattrs. However, I think I have found two problems (bugs? unsupported features?) with the approach and would love to hear your opinion.
But before I go into the details, a quick question upfront: Is this going to remain the "recommended" approach to unstructure objects from a class hierarchy? I am asking because I also saw #312 which seems about to be merged but I am not entirely sure how/if it's going to replace your described method.
So here are now the two issues I noticed:
slotted=False
. I guess this is probably due to due the changes defaults (see also Weird output while structuring unions with custom disambiguation function #267)? On the other hand, I wonder why your example then originally worked because it already usesdefine
instead ofattr.s
?from __future__ import annotations
and throws the following exception:Is the second issue related to #215 or is this a bug?
The text was updated successfully, but these errors were encountered: