@@ -20,6 +20,7 @@ class ArgInspector2 {
20
20
std::string arg = " (default arg inspector 2)" ;
21
21
};
22
22
class ArgAlwaysConverts {};
23
+
23
24
namespace pybind11 {
24
25
namespace detail {
25
26
template <>
@@ -105,6 +106,34 @@ struct type_caster<DestructionTester> {
105
106
} // namespace detail
106
107
} // namespace pybind11
107
108
109
+ // Define type caster outside of `pybind11::detail` and then alias it.
110
+ namespace other_lib {
111
+ struct MyType {};
112
+ // Corrupt `py` shorthand alias for surrounding context.
113
+ namespace py {}
114
+ // Corrupt unqualified relative `pybind11` namespace.
115
+ namespace pybind11 {}
116
+ // Correct alias.
117
+ namespace py_ = ::pybind11;
118
+ // Define caster. This is effectively no-op, we only ensure it compiles and we
119
+ // don't have any symbol collision when using macro mixin.
120
+ struct my_caster {
121
+ PYBIND11_TYPE_CASTER (MyType, py_::detail::const_name(" MyType" ));
122
+ bool load (py_::handle, bool ) { return true ; }
123
+
124
+ static py_::handle cast (const MyType &, py_::return_value_policy, py_::handle) {
125
+ return py_::bool_ (true ).release ();
126
+ }
127
+ };
128
+ } // namespace other_lib
129
+ // Effectively "alias" it into correct namespace (via inheritance).
130
+ namespace pybind11 {
131
+ namespace detail {
132
+ template <>
133
+ struct type_caster <other_lib::MyType> : public other_lib::my_caster {};
134
+ } // namespace detail
135
+ } // namespace pybind11
136
+
108
137
TEST_SUBMODULE (custom_type_casters, m) {
109
138
// test_custom_type_casters
110
139
@@ -175,4 +204,6 @@ TEST_SUBMODULE(custom_type_casters, m) {
175
204
m.def (" destruction_tester_cstats" ,
176
205
&ConstructorStats::get<DestructionTester>,
177
206
py::return_value_policy::reference);
207
+
208
+ m.def (" other_lib_type" , [](other_lib::MyType x) { return x; });
178
209
}
0 commit comments