pybind / pybind/pybind11

Binding a class/enum in multiple modules fails for statically linked code despite specifying module_local()

Open
#1,789 1 comment 1 reaction 0 assignees View on GitHub

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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.