mindvirus
mindvirus

Reputation: 5246

Wrapping C-enum in a Python module with Swig

I have a simple enum in C in myenum.h:

enum MyEnum {
    ONE,
    TWO,
    THREE
};

The problem is that when I map this to Python, I can only access the enum through the module name, not through MyEnum. So the values ONE, TWO, THREE are included with any other functions I define, instead of being contained with MyEnum.

My api.i file is:

%module api
%{
#include "myenum.h"
%}
%include "myenum.h"

I generate with SWIG

swig -builtin -python api.i

And import it into Python

import _api

And now I have to use the enum values from the _api module:

_api.ONE
_api.TWO
_api.THREE

While I want to use them like

_api.MyEnum.ONE
_api.MyEnum.TWO
_api.MyEnum.THREE

Does anyone know how I can accomplish this?

Upvotes: 9

Views: 7598

Answers (2)

Ian Stapleton Cordasco
Ian Stapleton Cordasco

Reputation: 28777

What you need to understand is that in C those names in your enum are not namespaced as they would be in Python. You should probably read something about how enums can be used before continuing.

Now note that since those are globally accessible names, they will not be namespaced in Python. Your best bet, is to create an object, along these lines:

class MyEnum:
   A = A
   B = B
   C = C

del(A, B, C)

Then A, B, C will only be accessible through _api.MyEnum.A, etc., and A, B, C won't be directly accessible.

Upvotes: 1

Mark Tolonen
Mark Tolonen

Reputation: 177725

There is a SWIG feature nspace that would do want you want, but unfortunately it isn't supported for Python yet. I've always had to define the enum in a struct for it to show up in the manner you desire in SWIG. Example:

%module tmp

%inline %{
struct MyEnum {
    enum { A,B,C };
};
%}

Result:

>>> import tmp
>>> tmp.MyEnum.A
0
>>> tmp.MyEnum.B
1
>>> tmp.MyEnum.C
2

Upvotes: 2

Related Questions