mirror of
https://github.com/pybind/pybind11.git
synced 2026-03-14 20:27:47 +00:00
Allow module-local classes to be loaded externally
The main point of `py::module_local` is to make the C++ -> Python cast unique so that returning/casting a C++ instance is well-defined. Unfortunately it also makes loading unique, but this isn't particularly desirable: when an instance contains `Type` instance there's no reason it shouldn't be possible to pass that instance to a bound function taking a `Type` parameter, even if that function is in another module. This commit solves the issue by allowing foreign module (and global) type loaders have a chance to load the value if the local module loader fails. The implementation here does this by storing a module-local loading function in a capsule in the python type, which we can then call if the local (and possibly global, if the local type is masking a global type) version doesn't work.
This commit is contained in:
@@ -14,13 +14,6 @@
|
||||
#include <pybind11/stl_bind.h>
|
||||
#include <numeric>
|
||||
|
||||
PYBIND11_MAKE_OPAQUE(LocalVec);
|
||||
PYBIND11_MAKE_OPAQUE(LocalVec2);
|
||||
PYBIND11_MAKE_OPAQUE(LocalMap);
|
||||
PYBIND11_MAKE_OPAQUE(NonLocalVec);
|
||||
PYBIND11_MAKE_OPAQUE(NonLocalMap);
|
||||
PYBIND11_MAKE_OPAQUE(NonLocalMap2);
|
||||
|
||||
TEST_SUBMODULE(local_bindings, m) {
|
||||
// test_local_bindings
|
||||
// Register a class with py::module_local:
|
||||
@@ -84,4 +77,21 @@ TEST_SUBMODULE(local_bindings, m) {
|
||||
m.def("load_vector_via_caster", [](std::vector<int> v) {
|
||||
return std::accumulate(v.begin(), v.end(), 0);
|
||||
});
|
||||
|
||||
// test_cross_module_calls
|
||||
m.def("return_self", [](LocalVec *v) { return v; });
|
||||
m.def("return_copy", [](const LocalVec &v) { return LocalVec(v); });
|
||||
|
||||
class Cat : public pets::Pet { public: Cat(std::string name) : Pet(name) {}; };
|
||||
py::class_<pets::Pet>(m, "Pet", py::module_local())
|
||||
.def("get_name", &pets::Pet::name);
|
||||
// Binding for local extending class:
|
||||
py::class_<Cat, pets::Pet>(m, "Cat")
|
||||
.def(py::init<std::string>());
|
||||
m.def("pet_name", [](pets::Pet &p) { return p.name(); });
|
||||
|
||||
py::class_<MixGL>(m, "MixGL").def(py::init<int>());
|
||||
m.def("get_gl_value", [](MixGL &o) { return o.i + 10; });
|
||||
|
||||
py::class_<MixGL2>(m, "MixGL2").def(py::init<int>());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user