diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index d788992df..c1d0bbc34 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -1421,6 +1421,17 @@ public: return cast_impl(std::forward(src), policy, parent, indices{}); } + // copied from the PYBIND11_TYPE_CASTER macro + template + static handle cast(T *src, return_value_policy policy, handle parent) { + if (!src) return none().release(); + if (policy == return_value_policy::take_ownership) { + auto h = cast(std::move(*src), policy, parent); delete src; return h; + } else { + return cast(*src, policy, parent); + } + } + static constexpr auto name = _("Tuple[") + concat(make_caster::name...) + _("]"); template using cast_op_type = type; diff --git a/tests/test_builtin_casters.cpp b/tests/test_builtin_casters.cpp index acb244691..acc9f8fb3 100644 --- a/tests/test_builtin_casters.cpp +++ b/tests/test_builtin_casters.cpp @@ -117,12 +117,16 @@ TEST_SUBMODULE(builtin_casters, m) { return std::make_pair(RValueCaster{}, std::make_tuple(RValueCaster{}, std::make_pair(RValueCaster{}, RValueCaster{}))); }); m.def("lvalue_nested", []() -> const decltype(lvnested) & { return lvnested; }); + static std::pair int_string_pair{2, "items"}; + m.def("int_string_pair", []() { return &int_string_pair; }); + // test_builtins_cast_return_none m.def("return_none_string", []() -> std::string * { return nullptr; }); m.def("return_none_char", []() -> const char * { return nullptr; }); m.def("return_none_bool", []() -> bool * { return nullptr; }); m.def("return_none_int", []() -> int * { return nullptr; }); m.def("return_none_float", []() -> float * { return nullptr; }); + m.def("return_none_pair", []() -> std::pair * { return nullptr; }); // test_none_deferred m.def("defer_none_cstring", [](char *) { return false; }); diff --git a/tests/test_builtin_casters.py b/tests/test_builtin_casters.py index a13acd5b9..af44bda71 100644 --- a/tests/test_builtin_casters.py +++ b/tests/test_builtin_casters.py @@ -250,6 +250,8 @@ def test_tuple(doc): assert m.rvalue_nested() == ("rvalue", ("rvalue", ("rvalue", "rvalue"))) assert m.lvalue_nested() == ("lvalue", ("lvalue", ("lvalue", "lvalue"))) + assert m.int_string_pair() == (2, "items") + def test_builtins_cast_return_none(): """Casters produced with PYBIND11_TYPE_CASTER() should convert nullptr to None""" @@ -258,6 +260,7 @@ def test_builtins_cast_return_none(): assert m.return_none_bool() is None assert m.return_none_int() is None assert m.return_none_float() is None + assert m.return_none_pair() is None def test_none_deferred():