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

#[pyclass] on enums MVP #2013

Closed
6 tasks
davidhewitt opened this issue Nov 21, 2021 · 8 comments · Fixed by #2034
Closed
6 tasks

#[pyclass] on enums MVP #2013

davidhewitt opened this issue Nov 21, 2021 · 8 comments · Fixed by #2034
Milestone

Comments

@davidhewitt
Copy link
Member

After #2002 it's legal to use #[pyclass] on enums that have only unit variants.

However, there's a few pieces which need finishing (at a minimum) before releasing this change in 0.16:

@davidhewitt
Copy link
Member Author

(Also, if anyone has strong opinion that this to be a separate #[pyenum] macro instead of part of #[pyclass], it would be better to split it out before 0.16. Personally I quite like having just the one #[pyclass] macro.)

@jovenlin0527
Copy link
Contributor

After #2002 it's legal to use #[pyclass] on enums that have only unit variants.

However, there's a few pieces which need finishing (at a minimum) before releasing this change in 0.16:

  • The generated class most likely wants a __richcmp__ implementation so that comparisons work as expected
  • __repr__ implementation

How about we introduce a new trait in src/class/impl_.rs that allows us to add default implementations for magic methods? This may be useful for other situations.

  • The generated class may want a metaclass to prevent subclassing

Related to #906.

It's not clear what's the expected behavior. Python's IntEnum subclasses from int, but that's not currently supported in PyO3, and it makes the enum immutable.

  • CHANGELOG entry

@davidhewitt
Copy link
Member Author

How about we introduce a new trait in src/class/impl_.rs that allows us to add default implementations for magic methods? This may be useful for other situations.

Agreed for sure. See also #1375 / #1376 which spoke about making "dataclass"-style #[pyclass] with hash, eq etc.

Related to #906.

Yes I think we can live without this for now as it's an ergonomics improvement in my eyes rather than core functionality.

It's not clear what's the expected behavior.

For C-style enums in #834, I would suggest that if comparisons against integers work as expected then that's probably a great starting point. We will probably want to get feedback from users as to how they want to interact with these things, and shouldn't be afraid of making changes after 0.16 once we do get some feedback.

@davidhewitt
Copy link
Member Author

We could also solve the subclassing-from-int issue if you think that's necessary. I don't think we're that far out from achieving it.

@jovenlin0527
Copy link
Contributor

For C-style enums in #834, I would suggest that if comparisons against integers work as expected then that's probably a great starting point. We will probably want to get feedback from users as to how they want to interact with these things, and shouldn't be afraid of making changes after 0.16 once we do get some feedback.

I don't have a strong opinion on how to implement that. I suggested subclassing int because that's what IntEnum does and I assumed that's what the user would expect, but I never used IntEnum so I'm not really sure. I think it's fine to implement that in a simple way (i.e. __int__ and __eq__) and see how users will think.

@jovenlin0527
Copy link
Contributor

jovenlin0527 commented Nov 24, 2021

On C-style enums. Rust generates a default discriminant for every variant that doesn't have a discriminant. But also Rust supports any expression (e.g. 2 + 2) as custom discriminants. That means if the user used such expression in their custom discriminants, then we cannot find the default discriminant for other variants without evaluating those expressions. I think we either ban any expressions that are not literals, or we don't support default discriminant. Or both.

By the way, do we treat all enums without data as C-style enums, even if there's no custom discriminant in the enum?

@birkenfeld
Copy link
Member

Why do you need to calculate the discriminants? Can't you just always use Enum::Var as uXX in the generated code?

@jovenlin0527
Copy link
Contributor

jovenlin0527 commented Nov 24, 2021

I didn't know you can cast them to uXX 😅. Yeah let's cast to usize.

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