Binding a class/enum in multiple modules fails for statically linked code despite specifying module_local()
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 18k
- Forks
- 2.3k
- Avg merge
- 5d 17h
- Merged PRs (30d)
- 10
Description
In our code, an enumeration needs to be wrapped in multiple modules. The entire code is statically linked into a single executable. Despite specifying py::module_local() for the enumeration binding, the code still fails with the following error:
ImportError: generic_type: type "type" is already registered!
The error seems to be due to a function static variable in the function registered_local_types_cpp() defined in include/pybind11/detail/internals.h
Is is possible to make the local type_info map actually unique for each module?
The same problem would manifest when binding an STL container in multiple modules.
The following code demonstrates the issue.
File: example1.cc
#include "pybind11/pybind11.h"
enum Color { RED, BLACK };
namespace py = pybind11;
PYBIND11_MODULE(example1, m) {
py::enum_(m, "Color", py::module_local())
.value("RED", Color::RED).export_values();
}
File: example2.cc
#include "pybind11/pybind11.h"
enum Color { RED, BLACK };
namespace py = pybind11;
PYBIND11_MODULE(example2, m) {
py::enum_(m, "Color", py::module_local())
.value("BLACK", Color::BLACK).export_values();
}
File: main.cc
#include <Python.h>
extern "C" {
void initexample1();
void initexample2();
}
int main(int argc, char *argv[]) {
Py_Initialize();
PyImport_AppendInittab("example1", initexample1);
PyImport_AppendInittab("example2", initexample2);
Py_Main(argc, argv);
}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with include/pybind11/detail/internals.h, especially registered_local_types_cpp(), and reproduce the failure using example1.cc, example2.cc, and main.cc with static linking. Trace how the local type_info map is shared between modules; done means module_local() permits both enum bindings, including the described STL-container case, without the duplicate-registration ImportError.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, python
- Domain
- backend-api-design
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100