Skip to content

Commit 31c0544

Browse files
committed
Better? implementation for previous commit
This avoids the introduction of a new return_value_policy. And it enforces copying of const pointers/references to ensure constness.
1 parent 12c38af commit 31c0544

File tree

6 files changed

+14
-27
lines changed

6 files changed

+14
-27
lines changed

include/pybind11/detail/common.h

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -434,14 +434,7 @@ 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,
438-
439-
/** This internally used policy only applies to C++ arguments passed
440-
to virtual methods overridden in Python. This effectively will result
441-
in the return_value_policy::reference policy usually.
442-
It is needed to suppress copying of const unique_ptr, which is
443-
otherwise applied to const refererences to ensure constness. */
444-
reference_override
437+
reference_internal
445438
};
446439

447440
PYBIND11_NAMESPACE_BEGIN(detail)

include/pybind11/detail/smart_holder_type_casters.h

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -473,13 +473,7 @@ struct smart_holder_type_caster : smart_holder_type_caster_load<T>,
473473

474474
static handle cast(T const &src, return_value_policy policy, handle parent) {
475475
// type_caster_base BEGIN
476-
// clang-format off
477-
if (policy == return_value_policy::automatic ||
478-
policy == return_value_policy::automatic_reference ||
479-
policy == return_value_policy::reference_override)
480-
policy = return_value_policy::copy; // copy ensures constness
481-
// clang-format on
482-
return cast(&src, policy, parent);
476+
return cast(&src, policy, parent); // copy ensures constness
483477
// type_caster_base END
484478
}
485479

@@ -494,6 +488,13 @@ struct smart_holder_type_caster : smart_holder_type_caster_load<T>,
494488
}
495489

496490
static handle cast(T const *src, return_value_policy policy, handle parent) {
491+
// enforce constness by using policy return_value_policy::copy
492+
if (policy != return_value_policy::reference_internal)
493+
policy = return_value_policy::copy;
494+
return cast(const_cast<T *>(src), policy, parent);
495+
}
496+
497+
static handle cast(T *src, return_value_policy policy, handle parent) {
497498
auto st = type_caster_base<T>::src_and_type(src);
498499
return cast_const_raw_ptr( // Originally type_caster_generic::cast.
499500
st.first,
@@ -504,10 +505,6 @@ struct smart_holder_type_caster : smart_holder_type_caster_load<T>,
504505
make_constructor::make_move_constructor(src));
505506
}
506507

507-
static handle cast(T *src, return_value_policy policy, handle parent) {
508-
return cast(const_cast<T const *>(src), policy, parent); // Mutbl2Const
509-
}
510-
511508
#if defined(_MSC_VER) && _MSC_VER < 1910
512509
// Working around MSVC 2015 bug. const-correctness is lost.
513510
// SMART_HOLDER_WIP: IMPROVABLE: make common code work with MSVC 2015.
@@ -567,7 +564,6 @@ struct smart_holder_type_caster : smart_holder_type_caster_load<T>,
567564

568565
case return_value_policy::automatic_reference:
569566
case return_value_policy::reference:
570-
case return_value_policy::reference_override:
571567
valueptr = src;
572568
wrapper->owned = false;
573569
break;
@@ -732,8 +728,8 @@ struct smart_holder_type_caster<std::unique_ptr<T, D>> : smart_holder_type_caste
732728
return none().release();
733729
if (policy == return_value_policy::automatic)
734730
policy = return_value_policy::reference_internal;
735-
else if (policy == return_value_policy::reference_override)
736-
policy = return_value_policy::reference;
731+
// allow reference only for overridden method calls (parent is None)
732+
else if (policy == return_value_policy::reference && !parent);
737733
else if (policy != return_value_policy::reference_internal)
738734
throw cast_error("Invalid return_value_policy for unique_ptr&");
739735
return smart_holder_type_caster<T>::cast(src.get(), policy, parent);

include/pybind11/detail/type_caster_base.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,6 @@ class type_caster_generic {
527527

528528
case return_value_policy::automatic_reference:
529529
case return_value_policy::reference:
530-
case return_value_policy::reference_override:
531530
valueptr = src;
532531
wrapper->owned = false;
533532
break;

include/pybind11/eigen.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,6 @@ struct type_caster<Type, enable_if_t<is_eigen_dense_plain<Type>::value>> {
303303
return eigen_array_cast<props>(*src);
304304
case return_value_policy::reference:
305305
case return_value_policy::automatic_reference:
306-
case return_value_policy::reference_override:
307306
return eigen_ref_array<props>(*src);
308307
case return_value_policy::reference_internal:
309308
return eigen_ref_array<props>(*src, parent);

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_override, typename... Args>
108+
template <return_value_policy policy = return_value_policy::reference, typename... Args>
109109
object operator()(Args &&...args) const;
110-
template <return_value_policy policy = return_value_policy::reference_override, typename... Args>
110+
template <return_value_policy policy = return_value_policy::reference, typename... Args>
111111
PYBIND11_DEPRECATED("call(...) was deprecated in favor of operator()(...)")
112112
object call(Args&&... args) const;
113113

tests/test_class_sh_basic.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def check_regex(expected, actual):
2929
(m.rtrn_rref, "rtrn_rref(_MvCtor){1}"),
3030
(m.rtrn_cref, "rtrn_cref_CpCtor"),
3131
(m.rtrn_mref, "rtrn_mref"),
32-
(m.rtrn_cptr, "rtrn_cptr"),
32+
(m.rtrn_cptr, "rtrn_cptr_CpCtor"),
3333
(m.rtrn_mptr, "rtrn_mptr"),
3434
(m.rtrn_shmp, "rtrn_shmp"),
3535
(m.rtrn_shcp, "rtrn_shcp"),

0 commit comments

Comments
 (0)