PyO3 / pyo3

Rust bindings for the Python interpreter
https://pyo3.rs
Other
11.44k stars 693 forks source link

Opt in to Unit Variants for Complex Enums with the `sealedclass` attribute #4300

Open Molkars opened 4 days ago

Molkars commented 4 days ago

One of the biggest limitations that I have encountered with this library is not being able to use unit variants in complex enums. I understand the decision to make unit variants a compilation error since the semantics of simple enums are drastically different from those of complex enums on the python side. However, this is a necessary feature for a project I am working on as I cannot change unit variants in order to maintain backwards compatibility for our vendors and to prevent massive refactoring in my project.

As a compromise, I propose supporting unit variants only behind a pyclass annotation option and therefore keeping the current behavior as the default behavior. I am not picky about what the option is named but my suggestions is #[pyclass(sealedclass)] option.

I have already implemented this feature in a local repo and will open a PR either later today or on Monday once I run all of the contribution prep on my machine here.

For reference, this feature is important to me because the codebase I am working on has the following pattern. We cannot make the unit variants non-unit for the sake of backwards compatibility with plugins our vendors have built and because it would cause a refactoring waterfall if we did.

#[pyclass(sealedclass)]
enum MyEnum {
    Thing1,
    Thing2,
    Thing3,
    Other(EndUserDefinedThing),
}

Another discussion I want to have, but might not quite fit here, is the separation of "true" enums from the pyclass attribute in the 1.0 release. I wrote the above a few days ago and have since had the idea of adding a #[pyenum] attribute for creating true python enums rather than grouping them under the pyclass attribute.