From ebbe066841e59745a8a7d9b7b8c1d3428d5728b9 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Thu, 4 Jul 2024 11:15:16 -0700 Subject: [PATCH] Implement `operator std::unique_ptr()`. Resolves all but 1 block of 4 BAKEIN_BREAK in test_class_sh_basic.py --- include/pybind11/cast.h | 6 +++- tests/test_class_sh_basic.py | 66 +++++++++++++++++------------------- 2 files changed, 37 insertions(+), 35 deletions(-) diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index c64d762565..a481a30e6c 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -996,6 +996,7 @@ struct move_only_holder_caster> bool load_value(value_and_holder &&v_h) { if (typeinfo->default_holder) { sh_load_helper.loaded_v_h = v_h; + sh_load_helper.loaded_v_h.type = get_type_info(typeid(type)); return true; } return false; // BAKEIN_WIP: What is the best behavior here? @@ -1005,7 +1006,10 @@ struct move_only_holder_caster> using cast_op_type = std::unique_ptr; explicit operator std::unique_ptr() { - throw std::runtime_error("WIP operator std::unique_ptr ()"); + if (typeinfo->default_holder) { + return sh_load_helper.template loaded_as_unique_ptr(); + } + pybind11_fail("Passing std::unique_ptr from Python to C++ requires smart_holder."); } static bool try_direct_conversions(handle) { return false; } diff --git a/tests/test_class_sh_basic.py b/tests/test_class_sh_basic.py index 8f44b90b6e..9872efab9f 100644 --- a/tests/test_class_sh_basic.py +++ b/tests/test_class_sh_basic.py @@ -48,8 +48,8 @@ def test_cast(rtrn_f, expected): (m.pass_mptr, "Mptr", "pass_mptr:Mptr(_MvCtor)*_MvCtor"), (m.pass_shmp, "Shmp", "pass_shmp:Shmp(_MvCtor)*_MvCtor"), (m.pass_shcp, "Shcp", "pass_shcp:Shcp(_MvCtor)*_MvCtor"), - # BAKEIN_BREAK (m.pass_uqmp, "Uqmp", "pass_uqmp:Uqmp(_MvCtor)*_MvCtor"), - # BAKEIN_BREAK (m.pass_uqcp, "Uqcp", "pass_uqcp:Uqcp(_MvCtor)*_MvCtor"), + (m.pass_uqmp, "Uqmp", "pass_uqmp:Uqmp(_MvCtor)*_MvCtor"), + (m.pass_uqcp, "Uqcp", "pass_uqcp:Uqcp(_MvCtor)*_MvCtor"), ], ) def test_load_with_mtxt(pass_f, mtxt, expected): @@ -59,8 +59,8 @@ def test_load_with_mtxt(pass_f, mtxt, expected): @pytest.mark.parametrize( ("pass_f", "rtrn_f", "expected"), [ - # (m.pass_udmp, m.rtrn_udmp, "pass_udmp:rtrn_udmp"), - # (m.pass_udcp, m.rtrn_udcp, "pass_udcp:rtrn_udcp"), + (m.pass_udmp, m.rtrn_udmp, "pass_udmp:rtrn_udmp"), + (m.pass_udcp, m.rtrn_udcp, "pass_udcp:rtrn_udcp"), ], ) def test_load_with_rtrn_f(pass_f, rtrn_f, expected): @@ -70,26 +70,26 @@ def test_load_with_rtrn_f(pass_f, rtrn_f, expected): @pytest.mark.parametrize( ("pass_f", "rtrn_f", "regex_expected"), [ - # BAKEIN_BREAK ( - # m.pass_udmp_del, - # m.rtrn_udmp_del, - # "pass_udmp_del:rtrn_udmp_del,udmp_deleter(_MvCtorTo)*_MvCtorTo", - # ), - # BAKEIN_BREAK ( - # m.pass_udcp_del, - # m.rtrn_udcp_del, - # "pass_udcp_del:rtrn_udcp_del,udcp_deleter(_MvCtorTo)*_MvCtorTo", - # ), - # BAKEIN_BREAK ( - # m.pass_udmp_del_nd, - # m.rtrn_udmp_del_nd, - # "pass_udmp_del_nd:rtrn_udmp_del_nd,udmp_deleter_nd(_MvCtorTo)*_MvCtorTo", - # ), - # BAKEIN_BREAK ( - # m.pass_udcp_del_nd, - # m.rtrn_udcp_del_nd, - # "pass_udcp_del_nd:rtrn_udcp_del_nd,udcp_deleter_nd(_MvCtorTo)*_MvCtorTo", - # ), + ( + m.pass_udmp_del, + m.rtrn_udmp_del, + "pass_udmp_del:rtrn_udmp_del,udmp_deleter(_MvCtorTo)*_MvCtorTo", + ), + ( + m.pass_udcp_del, + m.rtrn_udcp_del, + "pass_udcp_del:rtrn_udcp_del,udcp_deleter(_MvCtorTo)*_MvCtorTo", + ), + ( + m.pass_udmp_del_nd, + m.rtrn_udmp_del_nd, + "pass_udmp_del_nd:rtrn_udmp_del_nd,udmp_deleter_nd(_MvCtorTo)*_MvCtorTo", + ), + ( + m.pass_udcp_del_nd, + m.rtrn_udcp_del_nd, + "pass_udcp_del_nd:rtrn_udcp_del_nd,udcp_deleter_nd(_MvCtorTo)*_MvCtorTo", + ), ], ) def test_deleter_roundtrip(pass_f, rtrn_f, regex_expected): @@ -99,10 +99,10 @@ def test_deleter_roundtrip(pass_f, rtrn_f, regex_expected): @pytest.mark.parametrize( ("pass_f", "rtrn_f", "expected"), [ - # BAKEIN_BREAK (m.pass_uqmp, m.rtrn_uqmp, "pass_uqmp:rtrn_uqmp"), - # BAKEIN_BREAK (m.pass_uqcp, m.rtrn_uqcp, "pass_uqcp:rtrn_uqcp"), - # BAKEIN_BREAK (m.pass_udmp, m.rtrn_udmp, "pass_udmp:rtrn_udmp"), - # BAKEIN_BREAK (m.pass_udcp, m.rtrn_udcp, "pass_udcp:rtrn_udcp"), + (m.pass_uqmp, m.rtrn_uqmp, "pass_uqmp:rtrn_uqmp"), + (m.pass_uqcp, m.rtrn_uqcp, "pass_uqcp:rtrn_uqcp"), + (m.pass_udmp, m.rtrn_udmp, "pass_udmp:rtrn_udmp"), + (m.pass_udcp, m.rtrn_udcp, "pass_udcp:rtrn_udcp"), ], ) def test_pass_unique_ptr_disowns(pass_f, rtrn_f, expected): @@ -120,10 +120,10 @@ def test_pass_unique_ptr_disowns(pass_f, rtrn_f, expected): @pytest.mark.parametrize( ("pass_f", "rtrn_f"), [ - # BAKEIN_BREAK (m.pass_uqmp, m.rtrn_uqmp), - # BAKEIN_BREAK (m.pass_uqcp, m.rtrn_uqcp), - # BAKEIN_BREAK (m.pass_udmp, m.rtrn_udmp), - # BAKEIN_BREAK (m.pass_udcp, m.rtrn_udcp), + (m.pass_uqmp, m.rtrn_uqmp), + (m.pass_uqcp, m.rtrn_uqcp), + (m.pass_udmp, m.rtrn_udmp), + (m.pass_udcp, m.rtrn_udcp), ], ) def test_cannot_disown_use_count_ne_1(pass_f, rtrn_f): @@ -142,7 +142,6 @@ def test_unique_ptr_roundtrip(num_round_trips=1000): recycled = m.atyp("passenger") for _ in range(num_round_trips): id_orig = id(recycled) - pytest.skip("BAKEIN_BREAK: AttributeError unique_ptr_roundtrip") recycled = m.unique_ptr_roundtrip(recycled) assert re.match("passenger(_MvCtor)*_MvCtor", m.get_mtxt(recycled)) id_rtrn = id(recycled) @@ -207,7 +206,6 @@ def test_function_signatures(doc): doc(m.args_shared_ptr_const) == "args_shared_ptr_const(arg0: m.class_sh_basic.atyp) -> m.class_sh_basic.atyp" ) - pytest.skip("BAKEIN_BREAK: AttributeError args_unique_ptr") assert ( doc(m.args_unique_ptr) == "args_unique_ptr(arg0: m.class_sh_basic.atyp) -> m.class_sh_basic.atyp"