Made module_local types take precedence over global types

Attempting to mix py::module_local and non-module_local classes results
in some unexpected/undesirable behaviour:

- if a class is registered non-local by some other module, a later
  attempt to register it locally fails.  It doesn't need to: it is
  perfectly acceptable for the local registration to simply override
  the external global registration.
- going the other way (i.e. module `A` registers a type `T` locally,
  then `B` registers the same type `T` globally) causes a more serious
  issue: `A.T`'s constructors no longer work because the `self` argument
  gets converted to a `B.T`, which then fails to resolve.

Changing the cast precedence to prefer local over global fixes this and
makes it work more consistently, regardless of module load order.
This commit is contained in:
Jason Rhinelander
2017-08-04 13:05:12 -04:00
parent 2640c950ca
commit 4b159230d9
7 changed files with 76 additions and 7 deletions

View File

@@ -57,6 +57,18 @@ TEST_SUBMODULE(local_bindings, m) {
py::bind_vector<std::vector<NonLocal2>>(m, "LocalVec2", py::module_local());
py::bind_map<std::unordered_map<std::string, uint8_t>>(m, "NonLocalMap2", py::module_local(false));
// test_mixed_local_global
// We try this both with the global type registered first and vice versa (the order shouldn't
// matter).
m.def("register_mixed_global", [m]() {
bind_local<MixedGlobalLocal, 100>(m, "MixedGlobalLocal", py::module_local(false));
});
m.def("register_mixed_local", [m]() {
bind_local<MixedLocalGlobal, 1000>(m, "MixedLocalGlobal", py::module_local());
});
m.def("get_mixed_gl", [](int i) { return MixedGlobalLocal(i); });
m.def("get_mixed_lg", [](int i) { return MixedLocalGlobal(i); });
// test_internal_locals_differ
m.def("local_cpp_types_addr", []() { return (uintptr_t) &py::detail::registered_local_types_cpp(); });
}