Comments (4)
For those of you who found your way to this issue when attempting to structure self-referential types, here is a demonstration of how to make it work:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from typing import List, Optional, ForwardRef
import attr
from cattr import structure, unstructure, register_structure_hook
@attr.s
class Subattr(object):
a: int = attr.ib()
@attr.s
class Node(object):
value: int = attr.ib()
subattr: Optional[Subattr] = attr.ib(default=None)
children: List['Node'] = attr.ib(default=[])
def main():
child_with_attr_field = Node(value=1, children=[Node(value=2, subattr=Subattr(a=2))])
print(child_with_attr_field)
print(unstructure(child_with_attr_field))
print(structure(unstructure(child_with_attr_field), Node))
register_structure_hook(
ForwardRef("Node"), lambda d, t: structure(d, Node),
)
Notably, if you use the structure hook from the sample code in the issue description:
register_structure_hook(
ForwardRef("Node"), lambda d, t: Node(**d), # wrong
)
... then attributes that are themselves attr types will not structure as their attr classes.
Edited: The previous incorrect comment has been replaced with a useful one.
from cattrs.
Hi! Thanks for the detailed write up. I'll brood on this and get back to you.
from cattrs.
This script demos the issue:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from typing import List, Optional
from cattr import structure, unstructure
import attr
@attr.s
class Node(object):
value: int = attr.ib()
children: Optional[List['Node']] = attr.ib(default=None)
def main():
g = {
'value': 1,
'children': [
{'value': 3},
{'value': 4, 'children': [{'value':44}]},
{'value': 5, 'children': [{'value':55}]}
]
}
n = structure(g, Node)
print(n)
if __name__ == "__main__":
main()
from cattrs.
Apart from this issue being almost 6 years old, this actually works out of the box nowadays!
from __future__ import annotations
from attrs import Factory, define
from cattrs import structure, unstructure
@define
class Subattr:
a: int
@define
class Node:
value: int
subattr: Subattr | None = None
children: list[Node] = Factory(list)
child_with_attr_field = Node(value=1, children=[Node(value=2, subattr=Subattr(a=2))])
print(child_with_attr_field)
print(unstructure(child_with_attr_field))
print(structure(unstructure(child_with_attr_field), Node))
Also super cool to see how attrs, cattrs and Python typing in general have come a long way!
from cattrs.
Related Issues (20)
- Constructor selection for structuring HOT 7
- Tagged Union: How to do structure/unstructure hook(s) for particular member type? HOT 4
- A dictionary gets structured into a list without errors/warnings HOT 2
- Question: Correct use of converters HOT 3
- Documentation does not explain unstruct_collection_overrides' input HOT 4
- Detailed validation exception groups with hook errors HOT 2
- cattrs effectively disables attrs validation HOT 3
- Covert to defaultdict instead of plain dict HOT 4
- How to recursively unstructure with hooks? HOT 5
- Dataclass structuring fails with misleading error message.
- Default field conversion conflicts with user-defined field converter function HOT 3
- [macOS] Error when trying to run tests: `ImportError: cannot import name 'CodecOptions' from 'bson'` HOT 2
- How to hook into structuring of a simple dict? HOT 6
- Incorrect dispatch in Python 3.12 HOT 4
- Why does structuring of datetime in attrs class need a structure hook? HOT 1
- `prefer_attrib_converters` doesn't work when the field is aliased HOT 2
- Register structure hook only for optional types HOT 2
- TYPE_CHECKING and init=False HOT 5
- Problem with tagged union example HOT 3
- Subclass disambiguation for nested structures. HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cattrs.