Skip to content

Commit adc2cdd

Browse files
authored
fixed regression in STL type caster RVPs (fixes #1561) (#1603)
1 parent 9f73060 commit adc2cdd

File tree

5 files changed

+34
-6
lines changed

5 files changed

+34
-6
lines changed

.appveyor.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ image:
33
- Visual Studio 2017
44
- Visual Studio 2015
55
test: off
6+
skip_branch_with_pr: true
67
build:
78
parallel: true
89
platform:

include/pybind11/cast.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1614,8 +1614,9 @@ template <typename Return, typename SFINAE = void> struct return_value_policy_ov
16141614
template <typename Return> struct return_value_policy_override<Return,
16151615
detail::enable_if_t<std::is_base_of<type_caster_generic, make_caster<Return>>::value, void>> {
16161616
static return_value_policy policy(return_value_policy p) {
1617-
return !std::is_lvalue_reference<Return>::value && !std::is_pointer<Return>::value
1618-
? return_value_policy::move : p;
1617+
return !std::is_lvalue_reference<Return>::value &&
1618+
!std::is_pointer<Return>::value
1619+
? return_value_policy::move : p;
16191620
}
16201621
};
16211622

include/pybind11/stl.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ template <typename Type, typename Key> struct set_caster {
8383

8484
template <typename T>
8585
static handle cast(T &&src, return_value_policy policy, handle parent) {
86-
policy = return_value_policy_override<Key>::policy(policy);
86+
if (!std::is_lvalue_reference<T>::value)
87+
policy = return_value_policy_override<Key>::policy(policy);
8788
pybind11::set s;
8889
for (auto &&value : src) {
8990
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 {
119120
template <typename T>
120121
static handle cast(T &&src, return_value_policy policy, handle parent) {
121122
dict d;
122-
return_value_policy policy_key = return_value_policy_override<Key>::policy(policy);
123-
return_value_policy policy_value = return_value_policy_override<Value>::policy(policy);
123+
return_value_policy policy_key = policy;
124+
return_value_policy policy_value = policy;
125+
if (!std::is_lvalue_reference<T>::value) {
126+
policy_key = return_value_policy_override<Key>::policy(policy_key);
127+
policy_value = return_value_policy_override<Value>::policy(policy_value);
128+
}
124129
for (auto &&kv : src) {
125130
auto key = reinterpret_steal<object>(key_conv::cast(forward_like<T>(kv.first), policy_key, parent));
126131
auto value = reinterpret_steal<object>(value_conv::cast(forward_like<T>(kv.second), policy_value, parent));
@@ -161,7 +166,8 @@ template <typename Type, typename Value> struct list_caster {
161166
public:
162167
template <typename T>
163168
static handle cast(T &&src, return_value_policy policy, handle parent) {
164-
policy = return_value_policy_override<Value>::policy(policy);
169+
if (!std::is_lvalue_reference<T>::value)
170+
policy = return_value_policy_override<Value>::policy(policy);
165171
list l(src.size());
166172
size_t index = 0;
167173
for (auto &&value : src) {

tests/test_stl.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,4 +265,16 @@ TEST_SUBMODULE(stl, m) {
265265
py::return_value_policy::take_ownership);
266266

267267
m.def("array_cast_sequence", [](std::array<int, 3> x) { return x; });
268+
269+
/// test_issue_1561
270+
struct Issue1561Inner { std::string data; };
271+
struct Issue1561Outer { std::vector<Issue1561Inner> list; };
272+
273+
py::class_<Issue1561Inner>(m, "Issue1561Inner")
274+
.def(py::init<std::string>())
275+
.def_readwrite("data", &Issue1561Inner::data);
276+
277+
py::class_<Issue1561Outer>(m, "Issue1561Outer")
278+
.def(py::init<>())
279+
.def_readwrite("list", &Issue1561Outer::list);
268280
}

tests/test_stl.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,3 +220,11 @@ def test_stl_ownership():
220220

221221
def test_array_cast_sequence():
222222
assert m.array_cast_sequence((1, 2, 3)) == [1, 2, 3]
223+
224+
225+
def test_issue_1561():
226+
""" check fix for issue #1561 """
227+
bar = m.Issue1561Outer()
228+
bar.list = [m.Issue1561Inner('bar')]
229+
bar.list
230+
assert bar.list[0].data == 'bar'

0 commit comments

Comments
 (0)