fixed regression in STL type caster RVPs (fixes #1561)
diff --git a/.appveyor.yml b/.appveyor.yml index 5e96940..3d49d56 100644 --- a/.appveyor.yml +++ b/.appveyor.yml
@@ -3,6 +3,7 @@ - Visual Studio 2017 - Visual Studio 2015 test: off +skip_branch_with_pr: true build: parallel: true platform:
diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index 5529768..a21d6ba 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h
@@ -1614,8 +1614,9 @@ 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>> { static return_value_policy policy(return_value_policy p) { - return !std::is_lvalue_reference<Return>::value && !std::is_pointer<Return>::value - ? return_value_policy::move : p; + return !std::is_lvalue_reference<Return>::value && + !std::is_pointer<Return>::value + ? return_value_policy::move : p; } };
diff --git a/include/pybind11/stl.h b/include/pybind11/stl.h index 50828a0..2d29a96 100644 --- a/include/pybind11/stl.h +++ b/include/pybind11/stl.h
@@ -83,7 +83,8 @@ template <typename T> 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; for (auto &&value : src) { auto value_ = reinterpret_steal<object>(key_conv::cast(forward_like<T>(value), policy, parent)); @@ -119,8 +120,12 @@ template <typename T> static handle cast(T &&src, return_value_policy policy, handle parent) { dict d; - return_value_policy policy_key = return_value_policy_override<Key>::policy(policy); - return_value_policy policy_value = return_value_policy_override<Value>::policy(policy); + return_value_policy policy_key = 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) { 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)); @@ -161,7 +166,8 @@ public: template <typename T> 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()); size_t index = 0; for (auto &&value : src) {
diff --git a/tests/test_stl.cpp b/tests/test_stl.cpp index 0bb6433..3736885 100644 --- a/tests/test_stl.cpp +++ b/tests/test_stl.cpp
@@ -265,4 +265,16 @@ py::return_value_policy::take_ownership); 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); }
diff --git a/tests/test_stl.py b/tests/test_stl.py index 9e58223..ba71ca3 100644 --- a/tests/test_stl.py +++ b/tests/test_stl.py
@@ -220,3 +220,11 @@ def test_array_cast_sequence(): 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'