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

Possible to get a list of enum names from a header file? #180

Closed
smahm006 opened this issue Aug 2, 2023 · 9 comments
Closed

Possible to get a list of enum names from a header file? #180

smahm006 opened this issue Aug 2, 2023 · 9 comments

Comments

@smahm006
Copy link

smahm006 commented Aug 2, 2023

Greetings,

First of thank you so much for this package. I have a c++ header file which has about 30 or so enums declared in it, and instead of importing all 30 manually I'd like to import all the enums dynamically and save them to a variable.

The problem is that I cannot seem to find the name of the enums to import from cppyy, I have tried something like below but unfortunately the class names are only of the type such as uint8_t or int8_t.

import cppyy
cppyy.include("enums.h")

classes = cppyy.gbl.__dict__
for class_name, class_obj in classes.items():
    if isinstance(class_obj, type) and issubclass(class_obj, int):
        print(class_name)

I was wondering if it was possible to get the names of all the enums in a header file so I can dynamically import them.

@smahm006 smahm006 changed the title Possible to get a list of enums from a header file? Possible to get a list of enum names from a header file? Aug 2, 2023
@wlav
Copy link
Owner

wlav commented Aug 2, 2023

Not really sure that I understand the question ... a "header file" isn't a coherent unit as seen by the compiler (certainly not something that persists). Would if they all live in the same namespace, though. Otherwise, any such approach simply identifies all enums seen so far, including ones you may not be interested in.

Specific to the given code, __dict__ is just a place to cache results that have been found. The way to browse contents of a scope would be to use dir(), ie. dir(cppyy.gbl) and then use getattr. However, enums could be anonymous, in which case they won't appear as a type at all in dir() (nor, eventually, __dict__), only their values; or they could be different types, in which case they need not derive from int.

@smahm006
Copy link
Author

smahm006 commented Aug 2, 2023

When I try to read dir(cppyy.gbl) the enums don't show up in the list. Only if I manually call from cppyy.gbl import Enum1, Enum2 then they show up.

But I would like to avoid calling 30 imports for the 30 enums that exist in my file. The enums in my file are not anonymous and each have a specific name like Enum1, Enum2, etc....

@wlav
Copy link
Owner

wlav commented Aug 2, 2023

Can you post the file so that I can reproduce? A basic enum.h like so:

enum A { a, b };

shows that enum just fine:

>>> import cppyy
>>> cppyy.include("enum.h")
True
>>> dir(cppyy.gbl)
['A', ...
>>>

@smahm006
Copy link
Author

smahm006 commented Aug 2, 2023

I cannot post the full file but here is a portion to give you an idea. There are about 30 or so enums in the file and all have the same syntax as below, just different names and values:

enum DebugTypeEnum {
  DebugTypeEnum_UnknownDebugType = 0,
  DebugTypeEnum_LOG_EMERG = 1,
  DebugTypeEnum_LOG_ALERT = 2,
  DebugTypeEnum_LOG_CRIT = 3,
  DebugTypeEnum_LOG_ERR = 4,
  DebugTypeEnum_LOG_WARNING = 5,
  DebugTypeEnum_LOG_NOTICE = 6,
  DebugTypeEnum_LOG_INFO = 7,
  DebugTypeEnum_LOG_DEBUG = 8,
  DebugTypeEnum_LOG_DEVICE = 9,
  DebugTypeEnum_MIN = DebugTypeEnum_UnknownDebugType,
  DebugTypeEnum_MAX = DebugTypeEnum_LOG_DEVICE
};

inline const DebugTypeEnum (&EnumValuesDebugTypeEnum())[10] {
  static const DebugTypeEnum values[] = {
    DebugTypeEnum_UnknownDebugType,
    DebugTypeEnum_LOG_EMERG,
    DebugTypeEnum_LOG_ALERT,
    DebugTypeEnum_LOG_CRIT,
    DebugTypeEnum_LOG_ERR,
    DebugTypeEnum_LOG_WARNING,
    DebugTypeEnum_LOG_NOTICE,
    DebugTypeEnum_LOG_INFO,
    DebugTypeEnum_LOG_DEBUG,
    DebugTypeEnum_LOG_DEVICE
  };
  return values;
}

inline const char * const *EnumNamesDebugTypeEnum() {
  static const char * const names[] = {
    "UnknownDebugType",
    "LOG_EMERG",
    "LOG_ALERT",
    "LOG_CRIT",
    "LOG_ERR",
    "LOG_WARNING",
    "LOG_NOTICE",
    "LOG_INFO",
    "LOG_DEBUG",
    "LOG_DEVICE",
    nullptr
  };
  return names;
}

inline const char *EnumNameDebugTypeEnum(DebugTypeEnum e) {
  if (e < DebugTypeEnum_UnknownDebugType || e > DebugTypeEnum_LOG_DEVICE) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesDebugTypeEnum()[index];
}

@wlav
Copy link
Owner

wlav commented Aug 2, 2023

It does show up for me:

>>> dir(cppyy.gbl)
['CppyyLegacy', 'DebugTypeEnum', ...
>>> dir(cppyy.gbl.DebugTypeEnum)
['DebugTypeEnum_LOG_ALERT', 'DebugTypeEnum_LOG_CRIT', ...

If it doesn't give you the same result, what version/platform are we speaking here?

@smahm006
Copy link
Author

smahm006 commented Aug 3, 2023

cppyy==3.0.0
cppyy-backend==1.14.11
cppyy-cling==6.28.0

But I don't think it has to do with the version. The C++ project I am dealing with is quite large and I have many other include paths involved besides just the enums.h file.

@smahm006 smahm006 closed this as completed Aug 3, 2023
@smahm006 smahm006 reopened this Aug 3, 2023
@smahm006
Copy link
Author

smahm006 commented Aug 3, 2023

Closed by mistake, Here is my dir output...

>>> import cppyy
>>> cppyy.include("path_to_folder/enums.h")
True
>>> dir(cppyy.gbl)
['CppyyLegacy', '__add__', '__bool__', '__class__', '__delattr__', '__destruct__', '__dict__', '__dir__', '__dispatch__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__invert__', '__le__', '__lt__', '__module__', '__mul__', '__ne__', '__neg__', '__new__', '__pos__', '__python_owns__', '__radd__', '__reduce__', '__reduce_ex__', '__repr__', '__reshape__', '__rmul__', '__rsub__', '__rtruediv__', '__setattr__', '__sizeof__', '__smartptr__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__weakref__', 'int8_t', 'std', 'uint8_t']

@smahm006
Copy link
Author

smahm006 commented Aug 3, 2023

Interesting, so I created my own local test-enums.h with a single enum and that showed up in dir. So then I made a copy of my enums.h and moved it over to my python project repository, but dir() of that local enums.h is not showing the enums still...

Is there a limit to what dir() can show? Maybe there are too many enums for it to show?

@smahm006
Copy link
Author

smahm006 commented Aug 3, 2023

AHHHH I am such an idiot, the enums are all under a namespace. If I import the namespace then all the enums show up.

Man thank you so much for the help @wlav and thank you again for this package.

@smahm006 smahm006 closed this as completed Aug 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants