My big picture is to easily [de]serialize attrs classes which I am using for a PyQt5 tree model. They can allow multiple types of children within lists (a group node would be able to hold both other groups and parameters, for example).
import traceback
import typing
import attr
import cattr
@attr.s
class WithChild:
child = cattr.typed(
default=None,
type='WithChild',
)
@attr.s
class WithChildren:
children = cattr.typed(
default=attr.Factory(list),
type=typing.List['WithChildren'],
)
@attr.s
class WithUnion:
children = cattr.typed(
default=attr.Factory(list),
type=typing.List[typing.Union['WithUnion']]
)
@attr.s
class WithUnionTwo:
children = cattr.typed(
default=attr.Factory(list),
type=typing.List[typing.Union['WithUnion', WithChild]]
)
def tryit():
try:
cattr.structure({}, WithChild)
except:
print(' - - - - - - WithChild failed')
print(traceback.format_exc())
else:
print(' - - - - - - WithChild succeeded')
try:
cattr.structure({'children': [{}]}, WithChildren)
except:
print(' - - - - - - WithChildren failed')
print(traceback.format_exc())
else:
print(' - - - - - - WithChildren succeeded')
try:
cattr.structure({'children': [{}]}, WithUnion)
except:
print(' - - - - - - WithUnion failed')
print(traceback.format_exc())
else:
print(' - - - - - - WithUnion succeeded')
try:
cattr.structure({'children': [{}]}, WithUnionTwo)
except:
print(' - - - - - - WithUnionTwo failed')
print(traceback.format_exc())
else:
print(' - - - - - - WithUnionTwo succeeded')
print(' == == == == == == == == == == == == No registration\n')
tryit()
cattr.register_structure_hook('WithChild', lambda d, t: WithChild(**d))
cattr.register_structure_hook('WithChildren', lambda d, t: WithChildren(**d))
cattr.register_structure_hook('WithUnion', lambda d, t: WithUnion(**d))
cattr.register_structure_hook('WithUnionTwo', lambda d, t: WithUnionTwo(**d))
print(' == == == == == == == == == == == == Registered strings\n')
tryit()
cattr.register_structure_hook(
typing._ForwardRef('WithChild'),
lambda d, t: WithChild(**d),
)
cattr.register_structure_hook(
typing._ForwardRef('WithChildren'),
lambda d, t: WithChildren(**d),
)
cattr.register_structure_hook(
typing._ForwardRef('WithUnion'),
lambda d, t: WithUnion(**d),
)
cattr.register_structure_hook(
typing._ForwardRef('WithUnionTwo'),
lambda d, t: WithUnionTwo(**d),
)
print(' == == == == == == == == == == == == Registered typing._ForwardRef()\n')
tryit()
== == == == == == == == == == == == No registration
- - - - - - WithChild failed
Traceback (most recent call last):
File "/epc/t/472/p/venv/src/graham/src/graham/tests/test_cattrs_a.py", line 42, in tryit
cattr.structure({}, WithChild)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 171, in structure
return self.structure_func.dispatch(cl)(obj, cl)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 86, in <lambda>
lambda *args, **kwargs: self.structure_attrs(*args, **kwargs))
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 276, in structure_attrs_fromdict
converted = self._structure_attr_from_dict(a, name, obj)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 293, in _structure_attr_from_dict
return self._structure.dispatch(type_)(mapping.get(a.name), type_)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 229, in _structure_default
raise ValueError(msg)
ValueError: Unsupported type: WithChild. Register a structure hook for it.
- - - - - - WithChildren failed
Traceback (most recent call last):
File "/epc/t/472/p/venv/src/graham/src/graham/tests/test_cattrs_a.py", line 50, in tryit
cattr.structure({'children': [{}]}, WithChildren)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 171, in structure
return self.structure_func.dispatch(cl)(obj, cl)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 86, in <lambda>
lambda *args, **kwargs: self.structure_attrs(*args, **kwargs))
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 276, in structure_attrs_fromdict
converted = self._structure_attr_from_dict(a, name, obj)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 293, in _structure_attr_from_dict
return self._structure.dispatch(type_)(mapping.get(a.name), type_)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 303, in _structure_list
for e in obj]
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 303, in <listcomp>
for e in obj]
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 229, in _structure_default
raise ValueError(msg)
ValueError: Unsupported type: _ForwardRef('WithChildren'). Register a structure hook for it.
- - - - - - WithUnion failed
Traceback (most recent call last):
File "/epc/t/472/p/venv/src/graham/src/graham/tests/test_cattrs_a.py", line 58, in tryit
cattr.structure({'children': [{}]}, WithUnion)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 171, in structure
return self.structure_func.dispatch(cl)(obj, cl)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 86, in <lambda>
lambda *args, **kwargs: self.structure_attrs(*args, **kwargs))
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 276, in structure_attrs_fromdict
converted = self._structure_attr_from_dict(a, name, obj)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 293, in _structure_attr_from_dict
return self._structure.dispatch(type_)(mapping.get(a.name), type_)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 303, in _structure_list
for e in obj]
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 303, in <listcomp>
for e in obj]
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 229, in _structure_default
raise ValueError(msg)
ValueError: Unsupported type: _ForwardRef('WithUnion'). Register a structure hook for it.
- - - - - - WithUnionTwo failed
Traceback (most recent call last):
File "/epc/t/472/p/venv/src/graham/src/graham/tests/test_cattrs_a.py", line 66, in tryit
cattr.structure({'children': [{}]}, WithUnionTwo)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 171, in structure
return self.structure_func.dispatch(cl)(obj, cl)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 86, in <lambda>
lambda *args, **kwargs: self.structure_attrs(*args, **kwargs))
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 276, in structure_attrs_fromdict
converted = self._structure_attr_from_dict(a, name, obj)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 293, in _structure_attr_from_dict
return self._structure.dispatch(type_)(mapping.get(a.name), type_)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 303, in _structure_list
for e in obj]
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 303, in <listcomp>
for e in obj]
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 372, in _structure_union
cl = self._dis_func_cache(union)(obj)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 398, in _get_dis_func
raise ValueError('Only unions of attr classes supported '
ValueError: Only unions of attr classes supported currently. Register a loads hook manually.
== == == == == == == == == == == == Registered strings
- - - - - - WithChild failed
Traceback (most recent call last):
File "/epc/t/472/p/venv/src/graham/src/graham/tests/test_cattrs_a.py", line 42, in tryit
cattr.structure({}, WithChild)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 171, in structure
return self.structure_func.dispatch(cl)(obj, cl)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 86, in <lambda>
lambda *args, **kwargs: self.structure_attrs(*args, **kwargs))
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 276, in structure_attrs_fromdict
converted = self._structure_attr_from_dict(a, name, obj)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 293, in _structure_attr_from_dict
return self._structure.dispatch(type_)(mapping.get(a.name), type_)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 229, in _structure_default
raise ValueError(msg)
ValueError: Unsupported type: WithChild. Register a structure hook for it.
- - - - - - WithChildren failed
Traceback (most recent call last):
File "/epc/t/472/p/venv/src/graham/src/graham/tests/test_cattrs_a.py", line 50, in tryit
cattr.structure({'children': [{}]}, WithChildren)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 171, in structure
return self.structure_func.dispatch(cl)(obj, cl)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 86, in <lambda>
lambda *args, **kwargs: self.structure_attrs(*args, **kwargs))
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 276, in structure_attrs_fromdict
converted = self._structure_attr_from_dict(a, name, obj)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 293, in _structure_attr_from_dict
return self._structure.dispatch(type_)(mapping.get(a.name), type_)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 303, in _structure_list
for e in obj]
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 303, in <listcomp>
for e in obj]
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 229, in _structure_default
raise ValueError(msg)
ValueError: Unsupported type: _ForwardRef('WithChildren'). Register a structure hook for it.
- - - - - - WithUnion failed
Traceback (most recent call last):
File "/epc/t/472/p/venv/src/graham/src/graham/tests/test_cattrs_a.py", line 58, in tryit
cattr.structure({'children': [{}]}, WithUnion)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 171, in structure
return self.structure_func.dispatch(cl)(obj, cl)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 86, in <lambda>
lambda *args, **kwargs: self.structure_attrs(*args, **kwargs))
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 276, in structure_attrs_fromdict
converted = self._structure_attr_from_dict(a, name, obj)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 293, in _structure_attr_from_dict
return self._structure.dispatch(type_)(mapping.get(a.name), type_)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 303, in _structure_list
for e in obj]
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 303, in <listcomp>
for e in obj]
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 229, in _structure_default
raise ValueError(msg)
ValueError: Unsupported type: _ForwardRef('WithUnion'). Register a structure hook for it.
- - - - - - WithUnionTwo failed
Traceback (most recent call last):
File "/epc/t/472/p/venv/src/graham/src/graham/tests/test_cattrs_a.py", line 66, in tryit
cattr.structure({'children': [{}]}, WithUnionTwo)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 171, in structure
return self.structure_func.dispatch(cl)(obj, cl)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 86, in <lambda>
lambda *args, **kwargs: self.structure_attrs(*args, **kwargs))
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 276, in structure_attrs_fromdict
converted = self._structure_attr_from_dict(a, name, obj)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 293, in _structure_attr_from_dict
return self._structure.dispatch(type_)(mapping.get(a.name), type_)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 303, in _structure_list
for e in obj]
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 303, in <listcomp>
for e in obj]
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 372, in _structure_union
cl = self._dis_func_cache(union)(obj)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 398, in _get_dis_func
raise ValueError('Only unions of attr classes supported '
ValueError: Only unions of attr classes supported currently. Register a loads hook manually.
== == == == == == == == == == == == Registered typing._ForwardRef()
- - - - - - WithChild failed
Traceback (most recent call last):
File "/epc/t/472/p/venv/src/graham/src/graham/tests/test_cattrs_a.py", line 42, in tryit
cattr.structure({}, WithChild)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 171, in structure
return self.structure_func.dispatch(cl)(obj, cl)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 86, in <lambda>
lambda *args, **kwargs: self.structure_attrs(*args, **kwargs))
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 276, in structure_attrs_fromdict
converted = self._structure_attr_from_dict(a, name, obj)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 293, in _structure_attr_from_dict
return self._structure.dispatch(type_)(mapping.get(a.name), type_)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 229, in _structure_default
raise ValueError(msg)
ValueError: Unsupported type: WithChild. Register a structure hook for it.
- - - - - - WithChildren succeeded
- - - - - - WithUnion succeeded
- - - - - - WithUnionTwo failed
Traceback (most recent call last):
File "/epc/t/472/p/venv/src/graham/src/graham/tests/test_cattrs_a.py", line 66, in tryit
cattr.structure({'children': [{}]}, WithUnionTwo)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 171, in structure
return self.structure_func.dispatch(cl)(obj, cl)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 86, in <lambda>
lambda *args, **kwargs: self.structure_attrs(*args, **kwargs))
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 276, in structure_attrs_fromdict
converted = self._structure_attr_from_dict(a, name, obj)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 293, in _structure_attr_from_dict
return self._structure.dispatch(type_)(mapping.get(a.name), type_)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 303, in _structure_list
for e in obj]
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 303, in <listcomp>
for e in obj]
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 372, in _structure_union
cl = self._dis_func_cache(union)(obj)
File "/epc/t/472/p/venv/src/cattrs/cattr/converters.py", line 398, in _get_dis_func
raise ValueError('Only unions of attr classes supported '
ValueError: Only unions of attr classes supported currently. Register a loads hook manually.