fixed regression in STL type caster RVPs (fixes #1561)

This commit is contained in:
Wenzel Jakob 2018-11-09 13:22:13 +01:00
parent 9f73060cc7
commit 8986743b6d
5 changed files with 34 additions and 6 deletions

View File

@ -3,6 +3,7 @@ image:
- Visual Studio 2017 - Visual Studio 2017
- Visual Studio 2015 - Visual Studio 2015
test: off test: off
skip_branch_with_pr: true
build: build:
parallel: true parallel: true
platform: platform:

View File

@ -1614,8 +1614,9 @@ template <typename Return, typename SFINAE = void> struct return_value_policy_ov
template <typename Return> struct return_value_policy_override<Return, template <typename Return> struct return_value_policy_override<Return,
detail::enable_if_t<std::is_base_of<type_caster_generic, make_caster<Return>>::value, void>> { detail::enable_if_t<std::is_base_of<type_caster_generic, make_caster<Return>>::value, void>> {
static return_value_policy policy(return_value_policy p) { static return_value_policy policy(return_value_policy p) {
return !std::is_lvalue_reference<Return>::value && !std::is_pointer<Return>::value return !std::is_lvalue_reference<Return>::value &&
? return_value_policy::move : p; !std::is_pointer<Return>::value
? return_value_policy::move : p;
} }
}; };

View File

@ -83,7 +83,8 @@ template <typename Type, typename Key> struct set_caster {
template <typename T> template <typename T>
static handle cast(T &&src, return_value_policy policy, handle parent) { static handle cast(T &&src, return_value_policy policy, handle parent) {
policy = return_value_policy_override<Key>::policy(policy); if (!std::is_lvalue_reference<T>::value)
policy = return_value_policy_override<Key>::policy(policy);
pybind11::set s; pybind11::set s;
for (auto &&value : src) { for (auto &&value : src) {
auto value_ = reinterpret_steal<object>(key_conv::cast(forward_like<T>(value), policy, parent)); auto value_ = reinterpret_steal<object>(key_conv::cast(forward_like<T>(value), policy, parent));
@ -119,8 +120,12 @@ template <typename Type, typename Key, typename Value> struct map_caster {
template <typename T> template <typename T>
static handle cast(T &&src, return_value_policy policy, handle parent) { static handle cast(T &&src, return_value_policy policy, handle parent) {
dict d; dict d;
return_value_policy policy_key = return_value_policy_override<Key>::policy(policy); return_value_policy policy_key = policy;
return_value_policy policy_value = return_value_policy_override<Value>::policy(policy); return_value_policy policy_value = policy;
if (!std::is_lvalue_reference<T>::value) {
policy_key = return_value_policy_override<Key>::policy(policy_key);
policy_value = return_value_policy_override<Value>::policy(policy_value);
}
for (auto &&kv : src) { for (auto &&kv : src) {
auto key = reinterpret_steal<object>(key_conv::cast(forward_like<T>(kv.first), policy_key, parent)); auto key = reinterpret_steal<object>(key_conv::cast(forward_like<T>(kv.first), policy_key, parent));
auto value = reinterpret_steal<object>(value_conv::cast(forward_like<T>(kv.second), policy_value, parent)); auto value = reinterpret_steal<object>(value_conv::cast(forward_like<T>(kv.second), policy_value, parent));
@ -161,7 +166,8 @@ private:
public: public:
template <typename T> template <typename T>
static handle cast(T &&src, return_value_policy policy, handle parent) { static handle cast(T &&src, return_value_policy policy, handle parent) {
policy = return_value_policy_override<Value>::policy(policy); if (!std::is_lvalue_reference<T>::value)
policy = return_value_policy_override<Value>::policy(policy);
list l(src.size()); list l(src.size());
size_t index = 0; size_t index = 0;
for (auto &&value : src) { for (auto &&value : src) {

View File

@ -265,4 +265,16 @@ TEST_SUBMODULE(stl, m) {
py::return_value_policy::take_ownership); py::return_value_policy::take_ownership);
m.def("array_cast_sequence", [](std::array<int, 3> x) { return x; }); m.def("array_cast_sequence", [](std::array<int, 3> x) { return x; });
/// test_issue_1561
struct Issue1561Inner { std::string data; };
struct Issue1561Outer { std::vector<Issue1561Inner> list; };
py::class_<Issue1561Inner>(m, "Issue1561Inner")
.def(py::init<std::string>())
.def_readwrite("data", &Issue1561Inner::data);
py::class_<Issue1561Outer>(m, "Issue1561Outer")
.def(py::init<>())
.def_readwrite("list", &Issue1561Outer::list);
} }

View File

@ -220,3 +220,11 @@ def test_stl_ownership():
def test_array_cast_sequence(): def test_array_cast_sequence():
assert m.array_cast_sequence((1, 2, 3)) == [1, 2, 3] assert m.array_cast_sequence((1, 2, 3)) == [1, 2, 3]
def test_issue_1561():
""" check fix for issue #1561 """
bar = m.Issue1561Outer()
bar.list = [m.Issue1561Inner('bar')]
bar.list
assert bar.list[0].data == 'bar'