Wrap nested enum class

497 views
Skip to first unread message

Julianus Pfeuffer

unread,
Jan 12, 2022, 1:22:43 PM1/12/22
to cython-users
Hi,

does anyone know how I can wrap a nested enum class:

#mymodule.hpp
class Foo
{
  enum class MyEnum
  {
     A,B,C
  };
  enum class MyEnum2
  {
     A,B,C
  };

  int enumToInt(MyEnum e)
  {
      switch(e)
      {
         case MyEnum::A : return 1;
         case MyEnum::B : return 2;
         case MyEnum::C : return 3;
      }
   };
};

such that it is callable like this from python:

from mymodule import *
foo = Foo()
myenumA = Foo.MyEnum.A
assert(foo.enumToInt(myenumA) == 1)

For the pxd/pyx I tried many combinations of cdef'ing, cpdef'ing, putting
it inside the class, using an additional cdef extern from * namespace "Foo":
but nothing worked. Always a different error.
Note the second enum class is just to show the requirement to be able to use the same Enum values in different scopes.

Thanks a lot for any hints!

Best regards,
Julianus

da-woods

unread,
Jan 14, 2022, 7:06:02 PM1/14/22
to cython...@googlegroups.com
I can find at least two options that work:

cdef extern from *:
    cppclass Foo:
        enum class MyEnum "Foo::MyEnum":
            A, B, C
        int enumToInt(MyEnum)

def f():
    cdef Foo f;
    return f.enumToInt(Foo.MyEnum.A)

(using cname "Foo::MyEnum" because Cython doesn't prefix the nested class correctly by default)

Or abusing namespace to get the Foo prefix:

cdef extern from * namespace "Foo":
    enum class MyEnum:
            A, B, C

cdef extern from *:
    cppclass Foo:
        int enumToInt(MyEnum)

def f():
    cdef Foo f;
    return f.enumToInt(MyEnum.A)

I'm using Cython 3 alpha (and both probably require that)


--

---
You received this message because you are subscribed to the Google Groups "cython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cython-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/cython-users/cf6c8e6b-62fb-499a-b756-4976566561f5n%40googlegroups.com.


Craig de Stigter

unread,
Mar 4, 2022, 1:06:26 AM3/4/22
to cython-users
Hi

Did you actually get this working? I'm struggling with the same problem.

Writing similar code to the above almost makes it work, but there's no way to expose the enum to Python code, since the inner enum class can't be declared with cpdef.

Since I want to expose the values as a Python enum, the only workaround I found was to define a completely separate duplicate python enum and explicitly call it from my wrapper objects (code here). I'm using cython 3.0.0a10.

I'd really appreciate any kind of proper solution since the above commit is really hacky and awful.

thanks
Craig

Julianus Pfeuffer

unread,
Mar 4, 2022, 4:27:03 AM3/4/22
to cython...@googlegroups.com
Hi!

Unfortunately I took the same or a similar route than you.
I am creating a hidden _MyEnum python enum object and monkey patch MyClass with

class MyClass:
  MyEnum = _MyEnum

None of the Cython code could create a Python object for me.

The Cython header is here:

I can paste the generated implementation later but it is essentially the above-mentioned monkey patching.

You received this message because you are subscribed to a topic in the Google Groups "cython-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/cython-users/PpwhyIzqGyA/unsubscribe.
To unsubscribe from this group and all its topics, send an email to cython-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/cython-users/ee903731-58bc-44d4-8155-382b6d631d30n%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages