python-attrs / cattrs

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

Feature Request: Use dedicated (un)structure methods if available #394

Closed pohlt closed 9 months ago

pohlt commented 1 year ago

To (uns)structure certain objects, cattrs allows to register (un)structure hooks. This is a great way to allow (un)structuring of any object, in particular if I cannot modify the underlying classes.

If I have control over the classes, it could be easier to define a (un)structure function or property within the class itself, because this code would reside within each class. During (un)structuring, cattrs could look for the availability of such functions and use the accordingly.

One way to implement that would be to tell the converter to look for a certain method/property (_structure in the example below):

converter.register_structure_property("_structure")

What to you think?

BTW: Thanks a lot for cattrs. I love it!

Tinche commented 1 year ago

Howdy!

So this is actually pretty easy to set up I think. You need to use a predicate function, here's the code:

from attrs import define

from cattrs import Converter

@define
class MyClass:
    a: int

    @classmethod
    def structure(cls, data: dict):
        return cls(data["b"])  # Not a

c = Converter()

c.register_structure_hook_func(
    lambda t: hasattr(t, "structure"), lambda v, t: t.structure(v)
)

print(c.structure({"b": 1}, MyClass))

Since it's already a one-liner (depending on the length of your method name ;) maybe we just document this somewhere?

If you feel like contributing something more substantial, I'd be open to making this a strategy (see here).

pohlt commented 1 year ago

That's awesome, thanks a lot!

I was looking into register_structure_hook_func, but considered it unhelpful for my idea. D'oh! 🙅🏼 Let's see if I find the time to add it as a strategy.

pohlt commented 1 year ago

Here's a PR.

pohlt commented 1 year ago

Here's a new PR: #405

Tinche commented 9 months ago

Closing since this was merged.