Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
([#408](https://github.com/python-attrs/cattrs/pull/408))
- Fix structuring `Final` lists.
([#412](https://github.com/python-attrs/cattrs/issues/412))
- Fix certain cases of structuring `Annotated` types.
([#418](https://github.com/python-attrs/cattrs/issues/418))


## 23.1.2 (2023-06-02)
Expand Down
6 changes: 4 additions & 2 deletions src/cattrs/converters.py
Original file line number Diff line number Diff line change
Expand Up @@ -917,9 +917,11 @@ def gen_unstructure_annotated(self, type):
origin = type.__origin__
return self._unstructure_func.dispatch(origin)

def gen_structure_annotated(self, type):
def gen_structure_annotated(self, type) -> Callable:
"""A hook factory for annotated types."""
origin = type.__origin__
return self._structure_func.dispatch(origin)
hook = self._structure_func.dispatch(origin)
return lambda v, _: hook(v, origin)

def gen_unstructure_typeddict(self, cl: Any) -> Callable[[Dict], Dict]:
"""Generate a TypedDict unstructure function.
Expand Down
13 changes: 7 additions & 6 deletions tests/test_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -671,21 +671,22 @@ class Inner:
class Outer:
i: Annotated[Inner, "test"]
j: List[Annotated[Inner, "test"]]
k: Annotated[Union[Inner, None], "test"]

orig = Outer(Inner(1), [Inner(1)])
orig = Outer(Inner(1), [Inner(1)], Inner(1))
raw = converter.unstructure(orig)

assert raw == {"i": {"a": 1}, "j": [{"a": 1}]}
assert raw == {"i": {"a": 1}, "j": [{"a": 1}], "k": {"a": 1}}

structured = converter.structure(raw, Outer)
assert structured == orig

# Now register a hook and rerun the test.
converter.register_unstructure_hook(Inner, lambda v: {"a": 2})
converter.register_unstructure_hook(Inner, lambda _: {"a": 2})

raw = converter.unstructure(Outer(Inner(1), [Inner(1)]))
raw = converter.unstructure(Outer(Inner(1), [Inner(1)], Inner(1)))

assert raw == {"i": {"a": 2}, "j": [{"a": 2}]}
assert raw == {"i": {"a": 2}, "j": [{"a": 2}], "k": {"a": 2}}

structured = converter.structure(raw, Outer)
assert structured == Outer(Inner(2), [Inner(2)])
assert structured == Outer(Inner(2), [Inner(2)], Inner(2))