Skip to content

Commit 91f97ca

Browse files
authored
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 7cf53ae.
1 parent f5bc204 commit 91f97ca

File tree

1 file changed

+10
-5
lines changed

1 file changed

+10
-5
lines changed

include/pybind11/detail/smart_holder_type_casters.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -624,15 +624,18 @@ struct smart_holder_type_caster<std::shared_ptr<T>> : smart_holder_type_caster_l
624624

625625
static handle cast(const std::shared_ptr<T> &src, return_value_policy policy, handle parent) {
626626
if (policy != return_value_policy::automatic
627-
&& policy != return_value_policy::reference_internal) {
627+
&& policy != return_value_policy::reference_internal
628+
&& policy != return_value_policy::automatic_reference) {
628629
// SMART_HOLDER_WIP: IMPROVABLE: Error message.
629630
throw cast_error("Invalid return_value_policy for shared_ptr.");
630631
}
632+
if (!src)
633+
return none().release();
631634

632635
auto src_raw_ptr = src.get();
633636
auto st = type_caster_base<T>::src_and_type(src_raw_ptr);
634-
if (st.first == nullptr)
635-
return none().release(); // PyErr was set already.
637+
if (st.second == nullptr)
638+
return handle(); // no type info: error will be set already
636639

637640
void *src_raw_void_ptr = static_cast<void *>(src_raw_ptr);
638641
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
693696
// SMART_HOLDER_WIP: IMPROVABLE: Error message.
694697
throw cast_error("Invalid return_value_policy for unique_ptr.");
695698
}
699+
if (!src)
700+
return none().release();
696701

697702
auto src_raw_ptr = src.get();
698703
auto st = type_caster_base<T>::src_and_type(src_raw_ptr);
699-
if (st.first == nullptr)
700-
return none().release(); // PyErr was set already.
704+
if (st.second == nullptr)
705+
return handle(); // no type info: error will be set already
701706

702707
void *src_raw_void_ptr = static_cast<void *>(src_raw_ptr);
703708
const detail::type_info *tinfo = st.second;

0 commit comments

Comments
 (0)