File tree 2 files changed +49
-1
lines changed
2 files changed +49
-1
lines changed Original file line number Diff line number Diff line change @@ -146,4 +146,34 @@ TEST_SUBMODULE(callbacks, m) {
146
146
py::class_<CppBoundMethodTest>(m, " CppBoundMethodTest" )
147
147
.def (py::init<>())
148
148
.def (" triple" , [](CppBoundMethodTest &, int val) { return 3 * val; });
149
+
150
+ struct CppCopyable {
151
+ int value{};
152
+ };
153
+ py::class_<CppCopyable>(m, " CppCopyable" )
154
+ .def (py::init<>())
155
+ .def_readwrite (" value" , &CppCopyable::value);
156
+ // Works fine, as pybind is aware of the existing instance.
157
+ m.def (
158
+ " callback_mutate_copyable_py" ,
159
+ [](std::function<void (CppCopyable&)> f, CppCopyable& obj) {
160
+ f (obj);
161
+ });
162
+ // Does not work as expected, because pybind will copy the instance when
163
+ // binding.
164
+ m.def (
165
+ " callback_mutate_copyable_cpp_ref" ,
166
+ [](std::function<void (CppCopyable&)> f, int value) {
167
+ CppCopyable obj{value};
168
+ f (obj);
169
+ return obj;
170
+ });
171
+ // Works as expected, because pybind will not copy the instance.
172
+ m.def (
173
+ " callback_mutate_copyable_cpp_ptr" ,
174
+ [](std::function<void (CppCopyable*)> f, int value) {
175
+ CppCopyable obj{value};
176
+ f (&obj);
177
+ return obj;
178
+ });
149
179
}
Original file line number Diff line number Diff line change @@ -97,11 +97,29 @@ def test_cpp_function_roundtrip():
97
97
assert any (s in str (excinfo .value ) for s in ("missing 1 required positional argument" ,
98
98
"takes exactly 2 arguments" ))
99
99
100
-
101
100
def test_function_signatures (doc ):
102
101
assert doc (m .test_callback3 ) == "test_callback3(arg0: Callable[[int], int]) -> str"
103
102
assert doc (m .test_callback4 ) == "test_callback4() -> Callable[[int], int]"
104
103
105
104
106
105
def test_movable_object ():
107
106
assert m .callback_with_movable (lambda _ : None ) is True
107
+
108
+
109
+ def test_object_mutation ():
110
+ # Issue #1200
111
+ def incr (obj ):
112
+ obj .value += 1
113
+
114
+ obj = m .CppCopyable ()
115
+ assert obj .value == 0
116
+
117
+ m .callback_mutate_copyable_py (incr , obj )
118
+ assert obj .value == 1
119
+
120
+ obj = m .callback_mutate_copyable_cpp_ref (incr , 10 )
121
+ # WARNING: This this creates a COPY when passing to callback.
122
+ assert obj .value == 10
123
+
124
+ obj = m .callback_mutate_copyable_cpp_ptr (incr , 10 )
125
+ assert obj .value == 11
You can’t perform that action at this time.
0 commit comments