Skip to content

allow constructor customization of complex enum variants#4158

Merged
davidhewitt merged 5 commits into
PyO3:mainfrom
Icxolu:issue/4109
May 9, 2024
Merged

allow constructor customization of complex enum variants#4158
davidhewitt merged 5 commits into
PyO3:mainfrom
Icxolu:issue/4109

Conversation

@Icxolu

@Icxolu Icxolu commented May 4, 2024

Copy link
Copy Markdown
Member

This is an (experimental) idea I had to support customization of the macro generated constructors for complex enum variants.

This allow placing the the #[pyo3(signature = ...)] attribute on complex enum variants and applies it to the generated constructor.
This way all the normal functionality of signature customization can also be applied for these generated constructors.

What I'm not completely sure about is whether we should reuse the signature name here, or whether we should have have some kind of alias like #[pyo3(constructor = ...)]. On one hand people are already familiar with how signature works, but using it on an enum variant (or anything that's not a function for that matter) is not so intuitive.

Closes #4109

@davidhewitt

davidhewitt commented May 6, 2024

Copy link
Copy Markdown
Member

I like this idea! I'll try to review the full code tomorrow, though I have some initial thoughts about how this extends:

  • it would be awesome to support something like this for #[pyclass] to automatically generate the #[new] in that case too. Is signature the right name in that case? I feel like constructor, new, or even init might be stronger choices when it's adding a function to the class?
  • re signature vs constructor, the only conflict I can think of is that we might want to allow users to do something like constructor = "some_func" in cases where the auto-generated constructor isn't enough. Or maybe we should have #[new(MyVariant)] in #[pymethods] for that case, if that's technically viable?

@Icxolu

Icxolu commented May 6, 2024

Copy link
Copy Markdown
Member Author
  • it would be awesome to support something like this for #[pyclass] to automatically generate the #[new] in that case too. Is signature the right name in that case?

Yeah, that came up in #4109 (comment) too. I think that extension is a good argument to go with a more descriptive keyword for that context.

  • re signature vs constructor, the only conflict I can think of is that we might want to allow users to do something like constructor = "some_func"

Hmm, interesting idea. It might be pretty tricky to guarantee that the correct variant is constructed if we open this for users.

@davidhewitt

Copy link
Copy Markdown
Member
  • re signature vs constructor, the only conflict I can think of is that we might want to allow users to do something like constructor = "some_func"

Hmm, interesting idea. It might be pretty tricky to guarantee that the correct variant is constructed if we open this for users.

Ah, very true, I guess we probably cannot, which is a good reason not to add that. And they can always add their own #[staticmethod] or #[classmethod] which constructs the variants anyway.

@davidhewitt davidhewitt left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me! 👍

Just a few small suggestions, and this also needs documentation before it can be merged.

Comment thread pyo3-macros-backend/src/pyclass.rs Outdated
Comment thread pyo3-macros-backend/src/pyclass.rs Outdated
Comment thread pyo3-macros-backend/src/pyclass.rs
Comment thread pytests/src/enums.rs
@Icxolu

Icxolu commented May 9, 2024

Copy link
Copy Markdown
Member Author

I've added to the complex enum section of the guide and put the attribute in the pyclass options table. Is there any other place where we want to mention this?

@davidhewitt davidhewitt left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that's sufficient for now, thanks!

Comment thread pyo3-macros-backend/src/pyclass.rs Outdated
Comment on lines +725 to +727
Ok(quote! { #cls::#variant_name => #repr, })
})
.collect::<Result<TokenStream>>()?;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this collect can be made infallible again.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, yes. I reverted it to how it was before 👍

@davidhewitt davidhewitt added this pull request to the merge queue May 9, 2024
Merged via the queue into PyO3:main with commit 7beb64a May 9, 2024
@Icxolu Icxolu deleted the issue/4109 branch May 9, 2024 22:04
@EricLBuehler

Copy link
Copy Markdown

@davidhewitt, @Icxolu thank you for implementing this!

@Icxolu Icxolu mentioned this pull request May 10, 2024
6 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Default values in enum struct-variants

3 participants