Search code examples
c++python-3.xpybind11

PyBind11 'generic_type: type "" is already registered!' when importing two modules with the same enum


I'm importing two modules written in C++ using PyBind11 in my Python program. Both modules A & B export a enum with the same name. I'm importing both to do some testing and comparison.

Their code is like this:

Module A:

PYBIND11_MODULE(module_A, m) {

    py::enum_<ENUM_NAME>(m, "ENUM_NAME")
        .value("ENUM_VAL1", ENUM_VAL1)
        .export_values();

Module B:

PYBIND11_MODULE(module_B, m) {

    py::enum_<ENUM_NAME>(m, "ENUM_NAME")
        .value("ENUM_VAL2", ENUM_VAL2)
        .export_values();

When I import both of them with __import__(module_X) in Python I get this error:

generic_type: type "ENUM_NAME" is already registered!

Why does this happen? The enums are tied to the module right? Why would it matter if two modules have attributes with the same name?

I can of course just rename one, or just import one module at the time but I want to have the flexibility to have any name for any module.


Solution

  • The accepted answer have something wrong. You can mark your enum with Annotation py::module_local to export it locally.

    See: Example

        py::enum_<PHYSFS_FileType>(m, "PHYSFS_FileType", py::module_local())
            .value("PHYSFS_FILETYPE_REGULAR", PHYSFS_FileType::PHYSFS_FILETYPE_REGULAR)
            .value("PHYSFS_FILETYPE_DIRECTORY", PHYSFS_FileType::PHYSFS_FILETYPE_DIRECTORY)
            .value("PHYSFS_FILETYPE_SYMLINK", PHYSFS_FileType::PHYSFS_FILETYPE_SYMLINK)
            .value("PHYSFS_FILETYPE_OTHER", PHYSFS_FileType::PHYSFS_FILETYPE_OTHER)
        ;
    

    Furthermore See: Document Module-local class bindings.