smart_holder fixups (#3012)

* Drop constraints on casting of std::shared_ptr

std::shared_ptrs can be shared across python and C++ by design.

* 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!

* Return None for nullptr

* Revert "Drop constraints on casting of std::shared_ptr"

This reverts commit 7cf53ae8b4.
This commit is contained in:
Robert Haschke 2021-05-28 15:35:50 +02:00 committed by GitHub
parent f5bc2040bf
commit 91f97ca401
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -624,15 +624,18 @@ struct smart_holder_type_caster<std::shared_ptr<T>> : smart_holder_type_caster_l
static handle cast(const std::shared_ptr<T> &src, return_value_policy policy, handle parent) { static handle cast(const std::shared_ptr<T> &src, return_value_policy policy, handle parent) {
if (policy != return_value_policy::automatic if (policy != return_value_policy::automatic
&& policy != return_value_policy::reference_internal) { && policy != return_value_policy::reference_internal
&& policy != return_value_policy::automatic_reference) {
// SMART_HOLDER_WIP: IMPROVABLE: Error message. // SMART_HOLDER_WIP: IMPROVABLE: Error message.
throw cast_error("Invalid return_value_policy for shared_ptr."); throw cast_error("Invalid return_value_policy for shared_ptr.");
} }
if (!src)
return none().release();
auto src_raw_ptr = src.get(); auto src_raw_ptr = src.get();
auto st = type_caster_base<T>::src_and_type(src_raw_ptr); auto st = type_caster_base<T>::src_and_type(src_raw_ptr);
if (st.first == nullptr) if (st.second == nullptr)
return none().release(); // PyErr was set already. return handle(); // no type info: error will be set already
void *src_raw_void_ptr = static_cast<void *>(src_raw_ptr); void *src_raw_void_ptr = static_cast<void *>(src_raw_ptr);
const detail::type_info *tinfo = st.second; const detail::type_info *tinfo = st.second;
@ -693,11 +696,13 @@ struct smart_holder_type_caster<std::unique_ptr<T, D>> : smart_holder_type_caste
// SMART_HOLDER_WIP: IMPROVABLE: Error message. // SMART_HOLDER_WIP: IMPROVABLE: Error message.
throw cast_error("Invalid return_value_policy for unique_ptr."); throw cast_error("Invalid return_value_policy for unique_ptr.");
} }
if (!src)
return none().release();
auto src_raw_ptr = src.get(); auto src_raw_ptr = src.get();
auto st = type_caster_base<T>::src_and_type(src_raw_ptr); auto st = type_caster_base<T>::src_and_type(src_raw_ptr);
if (st.first == nullptr) if (st.second == nullptr)
return none().release(); // PyErr was set already. return handle(); // no type info: error will be set already
void *src_raw_void_ptr = static_cast<void *>(src_raw_ptr); void *src_raw_void_ptr = static_cast<void *>(src_raw_ptr);
const detail::type_info *tinfo = st.second; const detail::type_info *tinfo = st.second;