-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Why pybind11 generated enum type is not PEP 435 compatible. say, it doesn't have value attribute and it's not iterable. #2332
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
Comments
Because it predates You can use |
Thanks @bstaletic for the comments. So pybind11 doesn't have the plan to make enum type PEP-435 compatible to keep backward compatibility, right? |
There are no backwards compatibility concerns here. For
Or you can do it from python with As for |
got it. Thanks. |
Seems solved/answered? |
Coming back to this, I would love to have this in I have written some schema-ish stuff (like Hydra, but trying to integrate something like nptyping), and it's a bit painful to have to explicitly check if an enum is really a pybind11 enum... Additionally, I was playing with I plan to implement a generic function to provide the functionality that @YannickJadoul mentioned, but I would like to eventually upstream it. May PR sometime in the next 1-2 months. At a minimum, it will be documentation encoding Yannick's suggested workaround. |
Ah! Looks like it's already provided via
I think the issue that I want to check if it's a pybind11 enum still stands. I'll see if there's a way to hack in (This is assuming |
FWIW I have been used the implementation at https://gist.github.com/anntzer/96f27c0b88634dbc61862d08bff46d10 to get "pythonic" enums with pybind11 (i.e., enums that actually inherit from It'd be nice to have something similar built into pybind11. |
Just filed #2739 which at least adds the @anntzer Thanks! I took a glance at the implementation of The main challenges will be: (1) Ensure that |
Moving comment from #2739 (comment) (design discussion
Fancy! Didn't see that PR (should've searched lol) I do believe I have solution to accommodate the intent of #2704, but while still maintaining the current setup for
I'd be totes down for ditching Python 2! Also, FWIW, I don't think it's a huge deal to conditionally support certain aspects in Python 2. I think it'd be easy to transparently make the Python 3 flavor behave like |
For what I understand of the previous conversations on standard library enum support, this has always been the sticking point. I thought I would give it another attempt as a separate thing from enum_, but it still raises weird API design questions because it's seemingly impossible to wrap standard library enums with an API exactly like class_ and enum_. @wjakob has said previously that he would prefer to see enum_ rely on duck typing to act like standard library enums (#253 (comment)). I don't know if his opinion has changed, that is a fairly old comment after all, but I do think that it's going to give people want they want for 90% of use cases. It's probably the lowest friction way of improving the enum_ class and so long as we continue to keep them PEP 435 compatible, we still have the option of switching to true standard library enums in the future if someone can figure out how to do it. |
Thanks! Just to check:
Can I ask what you mean by "it"? The macro + FWIW Leveraging a Python base class may be simplified if we can simplify the instance registration system (e.g. decouple more complex stuff, so we could easily support this use case). |
I think that making the enum_ class look and act like an Enum is the lowest friction way. |
Back when #781 was still a thing, I did try to finish that pull request. You can guess that I got exactly nowhere. A bunch of times too. Even making
Arguably, that's just stupid, but it's perfectly valid with
To be fair, I haven't looked too deeply into @AWhetter's PR. The above is just what I remember from a few years back. |
py::stdenum("PyName", "enum.Enum")
.values({"name", value}, {"name", value}, ...) // or without the braces
.def("method", method_impl)
.def("method", method_impl) as you can always add methods later to the Python class (you can just (*) actually last time I checked (Edit: I guess using the C++-level destructor as "finalizer", as in #2704, would work...) |
I've filed an alternative draft implementation, #2744. I was wrong about This is one incantation of the duck-typed form that I believe Ashley mentioned above I believe this won't be as good as Antony's end-result (in that it requires reimplementation), but it's a step in that direction, and not a huge diff. I also don't think reimplementing * On this point, I tried this out here, but got segfaults here: |
See also #1177 - pybind11 enums aren't singletons, but the enum module creates singletons per PEP 435. |
I'll allow myself to suggest once again having a way to bind stdlib enums (e.g. with some variant of my gist above, but I'm not wedded to the implementation), as it turns out that stdlib enums are still gaining new features (https://docs.python.org/3.10/library/enum.html#enum.FlagBoundary in py3.10 (the metaclass kwarg will require a small change to the gist, but shouldn't be too tricky either)) and it seems better to just reuse their implementation rather than reimplementing everything again and again on pybind11's side. This can (should) even have a separate name ( |
I am wondering if there is a cleaner way to fix this by using / abusing |
I just want to note that with pybind11 2.10.0 the support for Python <3.5 (incl. 2.7) was removed, thus |
EDIT(eric): Deleted template text in body. Title describes issue sufficiently.
For reference: PEP 435
EDIT 2 (eric): See #253 per Ashley's mention.
The text was updated successfully, but these errors were encountered: