From 7cf53ae8b4f99c0382845acf8bc63b64924dc891 Mon Sep 17 00:00:00 2001 From: Robert Haschke Date: Thu, 20 May 2021 14:56:00 +0200 Subject: [PATCH 1/4] Drop constraints on casting of std::shared_ptr std::shared_ptrs can be shared across python and C++ by design. --- include/pybind11/detail/smart_holder_type_casters.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/include/pybind11/detail/smart_holder_type_casters.h b/include/pybind11/detail/smart_holder_type_casters.h index 22758e101d..8c2e6387ed 100644 --- a/include/pybind11/detail/smart_holder_type_casters.h +++ b/include/pybind11/detail/smart_holder_type_casters.h @@ -623,12 +623,6 @@ struct smart_holder_type_caster> : smart_holder_type_caster_l static constexpr auto name = _>(); static handle cast(const std::shared_ptr &src, return_value_policy policy, handle parent) { - if (policy != return_value_policy::automatic - && policy != return_value_policy::reference_internal) { - // SMART_HOLDER_WIP: IMPROVABLE: Error message. - throw cast_error("Invalid return_value_policy for shared_ptr."); - } - auto src_raw_ptr = src.get(); auto st = type_caster_base::src_and_type(src_raw_ptr); if (st.first == nullptr) From ba2e1315b48179677aa1f7ee9586699e66697824 Mon Sep 17 00:00:00 2001 From: Robert Haschke Date: Thu, 20 May 2021 21:23:24 +0200 Subject: [PATCH 2/4] Correctly report casting error It is important to return an empty handle. Simply returning None, would skip the error handling in simple_collector / unpacking_collector, although a python exception is set. A function call would then be processed with a (wrong) None argument! --- include/pybind11/detail/smart_holder_type_casters.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/pybind11/detail/smart_holder_type_casters.h b/include/pybind11/detail/smart_holder_type_casters.h index 8c2e6387ed..e4451d34e9 100644 --- a/include/pybind11/detail/smart_holder_type_casters.h +++ b/include/pybind11/detail/smart_holder_type_casters.h @@ -625,8 +625,8 @@ struct smart_holder_type_caster> : smart_holder_type_caster_l static handle cast(const std::shared_ptr &src, return_value_policy policy, handle parent) { auto src_raw_ptr = src.get(); auto st = type_caster_base::src_and_type(src_raw_ptr); - if (st.first == nullptr) - return none().release(); // PyErr was set already. + if (st.second == nullptr) + return handle(); // no type info: error will be set already void *src_raw_void_ptr = static_cast(src_raw_ptr); const detail::type_info *tinfo = st.second; @@ -690,8 +690,8 @@ struct smart_holder_type_caster> : smart_holder_type_caste auto src_raw_ptr = src.get(); auto st = type_caster_base::src_and_type(src_raw_ptr); - if (st.first == nullptr) - return none().release(); // PyErr was set already. + if (st.second == nullptr) + return handle(); // no type info: error will be set already void *src_raw_void_ptr = static_cast(src_raw_ptr); const detail::type_info *tinfo = st.second; From 3c92b9fbe6b05c254e7d20a7b9d8040c92029290 Mon Sep 17 00:00:00 2001 From: Robert Haschke Date: Thu, 20 May 2021 23:03:01 +0200 Subject: [PATCH 3/4] Return None for nullptr --- include/pybind11/detail/smart_holder_type_casters.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/pybind11/detail/smart_holder_type_casters.h b/include/pybind11/detail/smart_holder_type_casters.h index e4451d34e9..4189e93054 100644 --- a/include/pybind11/detail/smart_holder_type_casters.h +++ b/include/pybind11/detail/smart_holder_type_casters.h @@ -623,6 +623,9 @@ struct smart_holder_type_caster> : smart_holder_type_caster_l static constexpr auto name = _>(); static handle cast(const std::shared_ptr &src, return_value_policy policy, handle parent) { + if (!src) + return none().release(); + auto src_raw_ptr = src.get(); auto st = type_caster_base::src_and_type(src_raw_ptr); if (st.second == nullptr) @@ -687,6 +690,8 @@ struct smart_holder_type_caster> : smart_holder_type_caste // SMART_HOLDER_WIP: IMPROVABLE: Error message. throw cast_error("Invalid return_value_policy for unique_ptr."); } + if (!src) + return none().release(); auto src_raw_ptr = src.get(); auto st = type_caster_base::src_and_type(src_raw_ptr); From 307f11516be8c9eefc21af26f5edeca416884f07 Mon Sep 17 00:00:00 2001 From: Robert Haschke Date: Fri, 28 May 2021 14:38:47 +0200 Subject: [PATCH 4/4] Revert "Drop constraints on casting of std::shared_ptr" This reverts commit 7cf53ae8b4f99c0382845acf8bc63b64924dc891. --- include/pybind11/detail/smart_holder_type_casters.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/pybind11/detail/smart_holder_type_casters.h b/include/pybind11/detail/smart_holder_type_casters.h index 4189e93054..15ab81c58d 100644 --- a/include/pybind11/detail/smart_holder_type_casters.h +++ b/include/pybind11/detail/smart_holder_type_casters.h @@ -623,6 +623,12 @@ struct smart_holder_type_caster> : smart_holder_type_caster_l static constexpr auto name = _>(); static handle cast(const std::shared_ptr &src, return_value_policy policy, handle parent) { + if (policy != return_value_policy::automatic + && policy != return_value_policy::reference_internal + && policy != return_value_policy::automatic_reference) { + // SMART_HOLDER_WIP: IMPROVABLE: Error message. + throw cast_error("Invalid return_value_policy for shared_ptr."); + } if (!src) return none().release();