From cfc848a137bd99a172329091c01fe29aeb552098 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 11 Jan 2021 22:06:18 -0800 Subject: [PATCH] Retrieving smart_holder pointer in type_caster>::load, and using it cast_op operators. --- tests/test_classh_wip.cpp | 22 ++++++---------------- tests/test_classh_wip.py | 19 +++++++++++++++++-- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/tests/test_classh_wip.cpp b/tests/test_classh_wip.cpp index 3de45a438..1767af9d3 100644 --- a/tests/test_classh_wip.cpp +++ b/tests/test_classh_wip.cpp @@ -33,8 +33,8 @@ std::string pass_mpty_shcp(std::shared_ptr obj) { return "pass_shcp: std::unique_ptr rtrn_mpty_uqmp() { return std::unique_ptr(new mpty); } std::unique_ptr rtrn_mpty_uqcp() { return std::unique_ptr(new mpty); } -const char* pass_mpty_uqmp(std::unique_ptr) { return "load_uqmp"; } -const char* pass_mpty_uqcp(std::unique_ptr) { return "load_uqcp"; } +std::string pass_mpty_uqmp(std::unique_ptr obj) { return "pass_uqmp:" + obj->mtxt; } +std::string pass_mpty_uqcp(std::unique_ptr obj) { return "pass_uqcp:" + obj->mtxt; } } // namespace classh_wip } // namespace pybind11_tests @@ -147,7 +147,7 @@ struct type_caster> : smart_holder_type_caster_load< }; template <> -struct type_caster> { +struct type_caster> : smart_holder_type_caster_load { static constexpr auto name = _>(); static handle cast(std::unique_ptr&& /*src*/, @@ -158,16 +158,11 @@ struct type_caster> { template using cast_op_type = std::unique_ptr; - operator std::unique_ptr() { return rtrn_mpty_uqmp(); } - - bool load(handle src, bool /*convert*/) { - if (!isinstance(src)) return false; - return true; - } + operator std::unique_ptr() { return smhldr_ptr->as_unique_ptr(); } }; template <> -struct type_caster> { +struct type_caster> : smart_holder_type_caster_load { static constexpr auto name = _>(); static handle cast(std::unique_ptr&& /*src*/, @@ -178,12 +173,7 @@ struct type_caster> { template using cast_op_type = std::unique_ptr; - operator std::unique_ptr() { return rtrn_mpty_uqcp(); } - - bool load(handle src, bool /*convert*/) { - if (!isinstance(src)) return false; - return true; - } + operator std::unique_ptr() { return smhldr_ptr->as_unique_ptr(); } }; } // namespace detail diff --git a/tests/test_classh_wip.py b/tests/test_classh_wip.py index 7d6d0bb0f..4ecdee8b6 100644 --- a/tests/test_classh_wip.py +++ b/tests/test_classh_wip.py @@ -47,5 +47,20 @@ def test_cast_unique_ptr(): def test_load_unique_ptr(): - assert m.pass_mpty_uqmp(m.mpty()) == "load_uqmp" - assert m.pass_mpty_uqcp(m.mpty()) == "load_uqcp" + assert m.pass_mpty_uqmp(m.mpty("Uqmp")) == "pass_uqmp:Uqmp" + assert m.pass_mpty_uqcp(m.mpty("Uqcp")) == "pass_uqcp:Uqcp" + + +@pytest.mark.parametrize( + "pass_mpty, argm, rtrn", + [ + (m.pass_mpty_uqmp, "Uqmp", "pass_uqmp:Uqmp"), + (m.pass_mpty_uqcp, "Uqcp", "pass_uqcp:Uqcp"), + ], +) +def test_pass_unique_ptr_disowns(pass_mpty, argm, rtrn): + obj = m.mpty(argm) + assert pass_mpty(obj) == rtrn + with pytest.raises(RuntimeError) as exc_info: + m.pass_mpty_uqmp(obj) + assert str(exc_info.value) == "Cannot disown nullptr (as_unique_ptr)."