python-attrs / cattrs

Composable custom class converters for attrs, dataclasses and friends.
https://catt.rs
MIT License
779 stars 108 forks source link

Nested class structure #542

Closed csqzhang closed 1 month ago

csqzhang commented 1 month ago

Description

I want to use cattrs to (un)strcuture classes.

What I Did

import cattr
import attr
from cattrs.strategies import configure_tagged_union, include_subclasses

@attr.s(frozen=True, auto_attribs=True)
class A:
    pass

@attr.s(frozen=True, auto_attribs=True)
class B1(A):
    b: str

@attr.s(frozen=True, auto_attribs=True)
class B2(A):
    b: str
    a: A

CONVERTER = cattr.Converter()
union_strategy = partial(configure_tagged_union, tag_name="type_name")
include_subclasses(A, CONVERTER, union_strategy=union_strategy)

if __name__ == "__main__":
    instance = B1(b="1")
    r = CONVERTER.unstructure(instance)
    CONVERTER.structure(r, A)
    instance2 = B2(b="2", a=B1(b="1"))
    r2 = CONVERTER.unstructure(instance2)
    CONVERTER.structure(r2, A)

In the example above, we can (un)structure a B1 instance (e.g. instance) correctly. However, for a B2 instance (e.g. instance2), I can see catter unstructure it correctly, r2 looks correctly. However, I got B2(b='2', a=A()) back when I structure the r2 as A, which does not equal to the original instance2.

Tinche commented 1 month ago

Can confirm the issue. Working on a fix now ;)

Tinche commented 1 month ago

I've also added a test for this modeled on your case.

csqzhang commented 1 month ago

@Tinche thanks for the work. just wondering when the release will happen?

Tinche commented 1 month ago

I'm finishing it up, a couple of weeks probably.

Feel free to use git main if you're in a rush, I try to keep it very stable.