@@ -20,6 +20,7 @@ class ArgInspector2 {
2020 std::string arg = " (default arg inspector 2)" ;
2121};
2222class ArgAlwaysConverts {};
23+
2324namespace pybind11 {
2425namespace detail {
2526template <>
@@ -105,6 +106,34 @@ struct type_caster<DestructionTester> {
105106} // namespace detail
106107} // namespace pybind11
107108
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+
108137TEST_SUBMODULE (custom_type_casters, m) {
109138 // test_custom_type_casters
110139
@@ -175,4 +204,6 @@ TEST_SUBMODULE(custom_type_casters, m) {
175204 m.def (" destruction_tester_cstats" ,
176205 &ConstructorStats::get<DestructionTester>,
177206 py::return_value_policy::reference);
207+
208+ m.def (" other_lib_type" , [](other_lib::MyType x) { return x; });
178209}
0 commit comments