Skip to content

Commit b33bd59

Browse files
committed
Introduce return_value_policy::trampoline_reference
... to explicitly indicate a call from a trampoline dispatcher method. In this case, the C++ objects should be always passed by (modifyable) reference if required by the wrapped API. const references (or pointers) are still copied.
1 parent 03cd9d6 commit b33bd59

File tree

4 files changed

+13
-5
lines changed

4 files changed

+13
-5
lines changed

include/pybind11/detail/common.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,11 @@ enum class return_value_policy : uint8_t {
434434
collected while Python is still using the child. More advanced
435435
variations of this scheme are also possible using combinations of
436436
return_value_policy::reference and the keep_alive call policy */
437-
reference_internal
437+
reference_internal,
438+
439+
/* This internally-only used policy applies to C++ arguments passed
440+
to virtual methods overridden in Python to allow reference passing. */
441+
automatic_override
438442
};
439443

440444
PYBIND11_NAMESPACE_BEGIN(detail)

include/pybind11/detail/smart_holder_type_casters.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,8 @@ struct smart_holder_type_caster : smart_holder_type_caster_load<T>,
479479
// is redundant: T& automatically casts to T const&
480480

481481
static handle cast(T const *src, return_value_policy policy, handle parent) {
482+
if (policy == return_value_policy::automatic_override)
483+
policy = return_value_policy::reference;
482484
auto st = type_caster_base<T>::src_and_type(src);
483485
return cast_const_raw_ptr( // Originally type_caster_generic::cast.
484486
st.first,
@@ -716,8 +718,8 @@ struct smart_holder_type_caster<std::unique_ptr<T, D>> : smart_holder_type_caste
716718
return none().release();
717719
if (policy == return_value_policy::automatic)
718720
policy = return_value_policy::reference_internal;
719-
else if (policy == return_value_policy::reference && !parent)
720-
; // passing from trampoline dispatcher: no parent available
721+
else if (policy == return_value_policy::automatic_override)
722+
;
721723
else if (policy != return_value_policy::reference_internal)
722724
throw cast_error(
723725
"Invalid return_value_policy: unique_ptr const& expects reference_internal");

include/pybind11/detail/type_caster_base.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -899,6 +899,8 @@ template <typename type> class type_caster_base : public type_caster_generic {
899899
}
900900

901901
static handle cast(const itype *src, return_value_policy policy, handle parent) {
902+
if (policy == return_value_policy::automatic_override)
903+
policy = return_value_policy::reference;
902904
auto st = src_and_type(src);
903905
return type_caster_generic::cast(
904906
st.first, policy, parent, st.second,

include/pybind11/pytypes.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,9 @@ class object_api : public pyobject_tag {
105105
function will throw a `cast_error` exception. When the Python function
106106
call fails, a `error_already_set` exception is thrown.
107107
\endrst */
108-
template <return_value_policy policy = return_value_policy::reference, typename... Args>
108+
template <return_value_policy policy = return_value_policy::automatic_override, typename... Args>
109109
object operator()(Args &&...args) const;
110-
template <return_value_policy policy = return_value_policy::reference, typename... Args>
110+
template <return_value_policy policy = return_value_policy::automatic_override, typename... Args>
111111
PYBIND11_DEPRECATED("call(...) was deprecated in favor of operator()(...)")
112112
object call(Args&&... args) const;
113113

0 commit comments

Comments
 (0)