Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recursive Attrs class generation #299

Closed
kyteware opened this issue Sep 6, 2022 · 3 comments · Fixed by #627
Closed

Recursive Attrs class generation #299

kyteware opened this issue Sep 6, 2022 · 3 comments · Fixed by #627

Comments

@kyteware
Copy link

kyteware commented Sep 6, 2022

  • cattrs version: 22.1.0
  • Python version: 3.11.0-rc1
  • Operating System: Fedora Linux

Description

I would like an easy way to recursively generate attrs classes that have attributes of their type (eg Foo.foo: Foo). Obviously, you can't directly annotate attributes as being of the same type of the class, as the class is not yet generated when specifying attrs attributes. However, Python 3.11 introduces typing.Self, a shortcut to annotating the class. Cattrs could implement this, allowing users to avoid using __attrs_post_init__ to achieve this.

What I Did

# I would like to be able to do this:
@define
class Bar:
    baz: typing.Self = None

@define
class Foo:
    bar: Bar

structure({"bar": {"baz": {"baz": None}}}, Foo)
@Tinche
Copy link
Member

Tinche commented Aug 7, 2023

Interesting, I wasn't aware attributes could be annotates as Self but according to PEP 673, that's valid!

We don't support it yet, so I'll leave this open as an enhancement request.

Your annotation is a little incorrect though, it should be Self | None.

Until we fix the issue, you can use a stringified annotation instead, like this:

from attrs import define

from cattrs import structure


@define
class Bar:
    baz: "Bar | None" = None


@define
class Foo:
    bar: Bar


structure({"bar": {"baz": {"baz": None}}}, Foo)

This should work.

@PIG208
Copy link
Contributor

PIG208 commented Aug 8, 2023

Related discussion about the None default adding making the type annotation implicitly Optional: python/cpython#90353 (comment). This behavior got fixed in Python 3.11+, but it pertains to previous versions.

@kyteware
Copy link
Author

kyteware commented Aug 8, 2023

Sounds good. I don't use cattrs anymore, but I'm happy that this feature is getting looked at.

@Tinche Tinche linked a pull request Feb 12, 2025 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants