cd15869f41c056040e50b82dc4f5e70eddaaff05
2 tests/test_methods_and_attributes.cpp -- constructors, deconstructors, attribute access,
3 __str__, argument and return value conventions
5 Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
7 All rights reserved. Use of this source code is governed by a
8 BSD-style license that can be found in the LICENSE file.
11 #include "pybind11_tests.h"
12 #include "constructor_stats.h"
16 ExampleMandA() { print_default_created(this); }
17 ExampleMandA(int value
) : value(value
) { print_created(this, value
); }
18 ExampleMandA(const ExampleMandA
&e
) : value(e
.value
) { print_copy_created(this); }
19 ExampleMandA(ExampleMandA
&&e
) : value(e
.value
) { print_move_created(this); }
20 ~ExampleMandA() { print_destroyed(this); }
22 std::string
toString() {
23 return "ExampleMandA[value=" + std::to_string(value
) + "]";
26 void operator=(const ExampleMandA
&e
) { print_copy_assigned(this); value
= e
.value
; }
27 void operator=(ExampleMandA
&&e
) { print_move_assigned(this); value
= e
.value
; }
29 void add1(ExampleMandA other
) { value
+= other
.value
; } // passing by value
30 void add2(ExampleMandA
&other
) { value
+= other
.value
; } // passing by reference
31 void add3(const ExampleMandA
&other
) { value
+= other
.value
; } // passing by const reference
32 void add4(ExampleMandA
*other
) { value
+= other
->value
; } // passing by pointer
33 void add5(const ExampleMandA
*other
) { value
+= other
->value
; } // passing by const pointer
35 void add6(int other
) { value
+= other
; } // passing by value
36 void add7(int &other
) { value
+= other
; } // passing by reference
37 void add8(const int &other
) { value
+= other
; } // passing by const reference
38 void add9(int *other
) { value
+= *other
; } // passing by pointer
39 void add10(const int *other
) { value
+= *other
; } // passing by const pointer
41 ExampleMandA
self1() { return *this; } // return by value
42 ExampleMandA
&self2() { return *this; } // return by reference
43 const ExampleMandA
&self3() { return *this; } // return by const reference
44 ExampleMandA
*self4() { return this; } // return by pointer
45 const ExampleMandA
*self5() { return this; } // return by const pointer
47 int internal1() { return value
; } // return by value
48 int &internal2() { return value
; } // return by reference
49 const int &internal3() { return value
; } // return by const reference
50 int *internal4() { return &value
; } // return by pointer
51 const int *internal5() { return &value
; } // return by const pointer
53 py::str
overloaded() { return "()"; }
54 py::str
overloaded(int) { return "(int)"; }
55 py::str
overloaded(int, float) { return "(int, float)"; }
56 py::str
overloaded(float, int) { return "(float, int)"; }
57 py::str
overloaded(int, int) { return "(int, int)"; }
58 py::str
overloaded(float, float) { return "(float, float)"; }
59 py::str
overloaded(int) const { return "(int) const"; }
60 py::str
overloaded(int, float) const { return "(int, float) const"; }
61 py::str
overloaded(float, int) const { return "(float, int) const"; }
62 py::str
overloaded(int, int) const { return "(int, int) const"; }
63 py::str
overloaded(float, float) const { return "(float, float) const"; }
65 static py::str
overloaded(float) { return "static float"; }
70 struct TestProperties
{
72 static int static_value
;
74 int get() const { return value
; }
75 void set(int v
) { value
= v
; }
77 static int static_get() { return static_value
; }
78 static void static_set(int v
) { static_value
= v
; }
80 int TestProperties::static_value
= 1;
82 struct TestPropertiesOverride
: TestProperties
{
84 static int static_value
;
86 int TestPropertiesOverride::static_value
= 99;
94 const UserType
&get1() const { return v1
; }
95 const UserType
&get2() const { return v2
; }
96 UserType
get_rvalue() const { return v2
; }
97 void set1(int v
) { v1
.set(v
); }
98 void set2(int v
) { v2
.set(v
); }
100 UserType
TestPropRVP::sv1(1);
101 UserType
TestPropRVP::sv2(1);
103 // py::arg/py::arg_v testing: these arguments just record their argument when invoked
104 class ArgInspector1
{ public: std::string arg
= "(default arg inspector 1)"; };
105 class ArgInspector2
{ public: std::string arg
= "(default arg inspector 2)"; };
106 class ArgAlwaysConverts
{ };
107 namespace pybind11
{ namespace detail
{
108 template <> struct type_caster
<ArgInspector1
> {
110 PYBIND11_TYPE_CASTER(ArgInspector1
, _("ArgInspector1"));
112 bool load(handle src
, bool convert
) {
113 value
.arg
= "loading ArgInspector1 argument " +
114 std::string(convert
? "WITH" : "WITHOUT") + " conversion allowed. "
115 "Argument value = " + (std::string
) str(src
);
119 static handle
cast(const ArgInspector1
&src
, return_value_policy
, handle
) {
120 return str(src
.arg
).release();
123 template <> struct type_caster
<ArgInspector2
> {
125 PYBIND11_TYPE_CASTER(ArgInspector2
, _("ArgInspector2"));
127 bool load(handle src
, bool convert
) {
128 value
.arg
= "loading ArgInspector2 argument " +
129 std::string(convert
? "WITH" : "WITHOUT") + " conversion allowed. "
130 "Argument value = " + (std::string
) str(src
);
134 static handle
cast(const ArgInspector2
&src
, return_value_policy
, handle
) {
135 return str(src
.arg
).release();
138 template <> struct type_caster
<ArgAlwaysConverts
> {
140 PYBIND11_TYPE_CASTER(ArgAlwaysConverts
, _("ArgAlwaysConverts"));
142 bool load(handle
, bool convert
) {
146 static handle
cast(const ArgAlwaysConverts
&, return_value_policy
, handle
) {
147 return py::none().release();
152 // test_custom_caster_destruction
153 class DestructionTester
{
155 DestructionTester() { print_default_created(this); }
156 ~DestructionTester() { print_destroyed(this); }
157 DestructionTester(const DestructionTester
&) { print_copy_created(this); }
158 DestructionTester(DestructionTester
&&) { print_move_created(this); }
159 DestructionTester
&operator=(const DestructionTester
&) { print_copy_assigned(this); return *this; }
160 DestructionTester
&operator=(DestructionTester
&&) { print_move_assigned(this); return *this; }
162 namespace pybind11
{ namespace detail
{
163 template <> struct type_caster
<DestructionTester
> {
164 PYBIND11_TYPE_CASTER(DestructionTester
, _("DestructionTester"));
165 bool load(handle
, bool) { return true; }
167 static handle
cast(const DestructionTester
&, return_value_policy
, handle
) {
168 return py::bool_(true).release();
173 // Test None-allowed py::arg argument policy
174 class NoneTester
{ public: int answer
= 42; };
175 int none1(const NoneTester
&obj
) { return obj
.answer
; }
176 int none2(NoneTester
*obj
) { return obj
? obj
->answer
: -1; }
177 int none3(std::shared_ptr
<NoneTester
> &obj
) { return obj
? obj
->answer
: -1; }
178 int none4(std::shared_ptr
<NoneTester
> *obj
) { return obj
&& *obj
? (*obj
)->answer
: -1; }
179 int none5(std::shared_ptr
<NoneTester
> obj
) { return obj
? obj
->answer
: -1; }
184 StrIssue() = default;
185 StrIssue(int i
) : val
{i
} {}
188 // Issues #854, #910: incompatible function args when member function/pointer is in unregistered base class
189 class UnregisteredBase
{
191 void do_nothing() const {}
192 void increase_value() { rw_value
++; ro_value
+= 0.25; }
193 void set_int(int v
) { rw_value
= v
; }
194 int get_int() const { return rw_value
; }
195 double get_double() const { return ro_value
; }
197 double ro_value
= 1.25;
199 class RegisteredDerived
: public UnregisteredBase
{
201 using UnregisteredBase::UnregisteredBase
;
202 double sum() const { return rw_value
+ ro_value
; }
205 TEST_SUBMODULE(methods_and_attributes
, m
) {
206 // test_methods_and_attributes
207 py::class_
<ExampleMandA
> emna(m
, "ExampleMandA");
208 emna
.def(py::init
<>())
209 .def(py::init
<int>())
210 .def(py::init
<const ExampleMandA
&>())
211 .def("add1", &ExampleMandA::add1
)
212 .def("add2", &ExampleMandA::add2
)
213 .def("add3", &ExampleMandA::add3
)
214 .def("add4", &ExampleMandA::add4
)
215 .def("add5", &ExampleMandA::add5
)
216 .def("add6", &ExampleMandA::add6
)
217 .def("add7", &ExampleMandA::add7
)
218 .def("add8", &ExampleMandA::add8
)
219 .def("add9", &ExampleMandA::add9
)
220 .def("add10", &ExampleMandA::add10
)
221 .def("self1", &ExampleMandA::self1
)
222 .def("self2", &ExampleMandA::self2
)
223 .def("self3", &ExampleMandA::self3
)
224 .def("self4", &ExampleMandA::self4
)
225 .def("self5", &ExampleMandA::self5
)
226 .def("internal1", &ExampleMandA::internal1
)
227 .def("internal2", &ExampleMandA::internal2
)
228 .def("internal3", &ExampleMandA::internal3
)
229 .def("internal4", &ExampleMandA::internal4
)
230 .def("internal5", &ExampleMandA::internal5
)
231 #if defined(PYBIND11_OVERLOAD_CAST)
232 .def("overloaded", py::overload_cast
<>(&ExampleMandA::overloaded
))
233 .def("overloaded", py::overload_cast
<int>(&ExampleMandA::overloaded
))
234 .def("overloaded", py::overload_cast
<int, float>(&ExampleMandA::overloaded
))
235 .def("overloaded", py::overload_cast
<float, int>(&ExampleMandA::overloaded
))
236 .def("overloaded", py::overload_cast
<int, int>(&ExampleMandA::overloaded
))
237 .def("overloaded", py::overload_cast
<float, float>(&ExampleMandA::overloaded
))
238 .def("overloaded_float", py::overload_cast
<float, float>(&ExampleMandA::overloaded
))
239 .def("overloaded_const", py::overload_cast
<int >(&ExampleMandA::overloaded
, py::const_
))
240 .def("overloaded_const", py::overload_cast
<int, float>(&ExampleMandA::overloaded
, py::const_
))
241 .def("overloaded_const", py::overload_cast
<float, int>(&ExampleMandA::overloaded
, py::const_
))
242 .def("overloaded_const", py::overload_cast
<int, int>(&ExampleMandA::overloaded
, py::const_
))
243 .def("overloaded_const", py::overload_cast
<float, float>(&ExampleMandA::overloaded
, py::const_
))
245 .def("overloaded", static_cast<py::str (ExampleMandA::*)()>(&ExampleMandA::overloaded
))
246 .def("overloaded", static_cast<py::str (ExampleMandA::*)(int)>(&ExampleMandA::overloaded
))
247 .def("overloaded", static_cast<py::str (ExampleMandA::*)(int, float)>(&ExampleMandA::overloaded
))
248 .def("overloaded", static_cast<py::str (ExampleMandA::*)(float, int)>(&ExampleMandA::overloaded
))
249 .def("overloaded", static_cast<py::str (ExampleMandA::*)(int, int)>(&ExampleMandA::overloaded
))
250 .def("overloaded", static_cast<py::str (ExampleMandA::*)(float, float)>(&ExampleMandA::overloaded
))
251 .def("overloaded_float", static_cast<py::str (ExampleMandA::*)(float, float)>(&ExampleMandA::overloaded
))
252 .def("overloaded_const", static_cast<py::str (ExampleMandA::*)(int ) const>(&ExampleMandA::overloaded
))
253 .def("overloaded_const", static_cast<py::str (ExampleMandA::*)(int, float) const>(&ExampleMandA::overloaded
))
254 .def("overloaded_const", static_cast<py::str (ExampleMandA::*)(float, int) const>(&ExampleMandA::overloaded
))
255 .def("overloaded_const", static_cast<py::str (ExampleMandA::*)(int, int) const>(&ExampleMandA::overloaded
))
256 .def("overloaded_const", static_cast<py::str (ExampleMandA::*)(float, float) const>(&ExampleMandA::overloaded
))
258 // test_no_mixed_overloads
259 // Raise error if trying to mix static/non-static overloads on the same name:
260 .def_static("add_mixed_overloads1", []() {
261 auto emna
= py::reinterpret_borrow
<py::class_
<ExampleMandA
>>(py::module::import("pybind11_tests.methods_and_attributes").attr("ExampleMandA"));
262 emna
.def ("overload_mixed1", static_cast<py::str (ExampleMandA::*)(int, int)>(&ExampleMandA::overloaded
))
263 .def_static("overload_mixed1", static_cast<py::str ( *)(float )>(&ExampleMandA::overloaded
));
265 .def_static("add_mixed_overloads2", []() {
266 auto emna
= py::reinterpret_borrow
<py::class_
<ExampleMandA
>>(py::module::import("pybind11_tests.methods_and_attributes").attr("ExampleMandA"));
267 emna
.def_static("overload_mixed2", static_cast<py::str ( *)(float )>(&ExampleMandA::overloaded
))
268 .def ("overload_mixed2", static_cast<py::str (ExampleMandA::*)(int, int)>(&ExampleMandA::overloaded
));
270 .def("__str__", &ExampleMandA::toString
)
271 .def_readwrite("value", &ExampleMandA::value
);
274 // Issue #443: can't call copied methods in Python 3
275 emna
.attr("add2b") = emna
.attr("add2");
277 // test_properties, test_static_properties, test_static_cls
278 py::class_
<TestProperties
>(m
, "TestProperties")
280 .def_readonly("def_readonly", &TestProperties::value
)
281 .def_readwrite("def_readwrite", &TestProperties::value
)
282 .def_property_readonly("def_property_readonly", &TestProperties::get
)
283 .def_property("def_property", &TestProperties::get
, &TestProperties::set
)
284 .def_readonly_static("def_readonly_static", &TestProperties::static_value
)
285 .def_readwrite_static("def_readwrite_static", &TestProperties::static_value
)
286 .def_property_readonly_static("def_property_readonly_static",
287 [](py::object
) { return TestProperties::static_get(); })
288 .def_property_static("def_property_static",
289 [](py::object
) { return TestProperties::static_get(); },
290 [](py::object
, int v
) { TestProperties::static_set(v
); })
291 .def_property_static("static_cls",
292 [](py::object cls
) { return cls
; },
293 [](py::object cls
, py::function f
) { f(cls
); });
295 py::class_
<TestPropertiesOverride
, TestProperties
>(m
, "TestPropertiesOverride")
297 .def_readonly("def_readonly", &TestPropertiesOverride::value
)
298 .def_readonly_static("def_readonly_static", &TestPropertiesOverride::static_value
);
300 auto static_get1
= [](py::object
) -> const UserType
& { return TestPropRVP::sv1
; };
301 auto static_get2
= [](py::object
) -> const UserType
& { return TestPropRVP::sv2
; };
302 auto static_set1
= [](py::object
, int v
) { TestPropRVP::sv1
.set(v
); };
303 auto static_set2
= [](py::object
, int v
) { TestPropRVP::sv2
.set(v
); };
304 auto rvp_copy
= py::return_value_policy::copy
;
306 // test_property_return_value_policies
307 py::class_
<TestPropRVP
>(m
, "TestPropRVP")
309 .def_property_readonly("ro_ref", &TestPropRVP::get1
)
310 .def_property_readonly("ro_copy", &TestPropRVP::get2
, rvp_copy
)
311 .def_property_readonly("ro_func", py::cpp_function(&TestPropRVP::get2
, rvp_copy
))
312 .def_property("rw_ref", &TestPropRVP::get1
, &TestPropRVP::set1
)
313 .def_property("rw_copy", &TestPropRVP::get2
, &TestPropRVP::set2
, rvp_copy
)
314 .def_property("rw_func", py::cpp_function(&TestPropRVP::get2
, rvp_copy
), &TestPropRVP::set2
)
315 .def_property_readonly_static("static_ro_ref", static_get1
)
316 .def_property_readonly_static("static_ro_copy", static_get2
, rvp_copy
)
317 .def_property_readonly_static("static_ro_func", py::cpp_function(static_get2
, rvp_copy
))
318 .def_property_static("static_rw_ref", static_get1
, static_set1
)
319 .def_property_static("static_rw_copy", static_get2
, static_set2
, rvp_copy
)
320 .def_property_static("static_rw_func", py::cpp_function(static_get2
, rvp_copy
), static_set2
)
321 // test_property_rvalue_policy
322 .def_property_readonly("rvalue", &TestPropRVP::get_rvalue
)
323 .def_property_readonly_static("static_rvalue", [](py::object
) { return UserType(1); });
325 // test_metaclass_override
326 struct MetaclassOverride
{ };
327 py::class_
<MetaclassOverride
>(m
, "MetaclassOverride", py::metaclass((PyObject
*) &PyType_Type
))
328 .def_property_readonly_static("readonly", [](py::object
) { return 1; });
330 #if !defined(PYPY_VERSION)
331 // test_dynamic_attributes
334 DynamicClass() { print_default_created(this); }
335 ~DynamicClass() { print_destroyed(this); }
337 py::class_
<DynamicClass
>(m
, "DynamicClass", py::dynamic_attr())
340 class CppDerivedDynamicClass
: public DynamicClass
{ };
341 py::class_
<CppDerivedDynamicClass
, DynamicClass
>(m
, "CppDerivedDynamicClass")
345 // test_noconvert_args
347 // Test converting. The ArgAlwaysConverts is just there to make the first no-conversion pass
348 // fail so that our call always ends up happening via the second dispatch (the one that allows
352 ArgInspector1
f(ArgInspector1 a
, ArgAlwaysConverts
) { return a
; }
353 std::string
g(ArgInspector1 a
, const ArgInspector1
&b
, int c
, ArgInspector2
*d
, ArgAlwaysConverts
) {
354 return a
.arg
+ "\n" + b
.arg
+ "\n" + std::to_string(c
) + "\n" + d
->arg
;
356 static ArgInspector2
h(ArgInspector2 a
, ArgAlwaysConverts
) { return a
; }
358 py::class_
<ArgInspector
>(m
, "ArgInspector")
360 .def("f", &ArgInspector::f
, py::arg(), py::arg() = ArgAlwaysConverts())
361 .def("g", &ArgInspector::g
, "a"_a
.noconvert(), "b"_a
, "c"_a
.noconvert()=13, "d"_a
=ArgInspector2(), py::arg() = ArgAlwaysConverts())
362 .def_static("h", &ArgInspector::h
, py::arg().noconvert(), py::arg() = ArgAlwaysConverts())
364 m
.def("arg_inspect_func", [](ArgInspector2 a
, ArgInspector1 b
, ArgAlwaysConverts
) { return a
.arg
+ "\n" + b
.arg
; },
365 py::arg().noconvert(false), py::arg_v(nullptr, ArgInspector1()).noconvert(true), py::arg() = ArgAlwaysConverts());
367 m
.def("floats_preferred", [](double f
) { return 0.5 * f
; }, py::arg("f"));
368 m
.def("floats_only", [](double f
) { return 0.5 * f
; }, py::arg("f").noconvert());
369 m
.def("ints_preferred", [](int i
) { return i
/ 2; }, py::arg("i"));
370 m
.def("ints_only", [](int i
) { return i
/ 2; }, py::arg("i").noconvert());
372 // test_bad_arg_default
373 // Issue/PR #648: bad arg default debugging output
375 m
.attr("debug_enabled") = true;
377 m
.attr("debug_enabled") = false;
379 m
.def("bad_arg_def_named", []{
380 auto m
= py::module::import("pybind11_tests");
381 m
.def("should_fail", [](int, UnregisteredType
) {}, py::arg(), py::arg("a") = UnregisteredType());
383 m
.def("bad_arg_def_unnamed", []{
384 auto m
= py::module::import("pybind11_tests");
385 m
.def("should_fail", [](int, UnregisteredType
) {}, py::arg(), py::arg() = UnregisteredType());
389 py::class_
<NoneTester
, std::shared_ptr
<NoneTester
>>(m
, "NoneTester")
391 m
.def("no_none1", &none1
, py::arg().none(false));
392 m
.def("no_none2", &none2
, py::arg().none(false));
393 m
.def("no_none3", &none3
, py::arg().none(false));
394 m
.def("no_none4", &none4
, py::arg().none(false));
395 m
.def("no_none5", &none5
, py::arg().none(false));
396 m
.def("ok_none1", &none1
);
397 m
.def("ok_none2", &none2
, py::arg().none(true));
398 m
.def("ok_none3", &none3
);
399 m
.def("ok_none4", &none4
, py::arg().none(true));
400 m
.def("ok_none5", &none5
);
403 // Issue #283: __str__ called on uninitialized instance when constructor arguments invalid
404 py::class_
<StrIssue
>(m
, "StrIssue")
405 .def(py::init
<int>())
407 .def("__str__", [](const StrIssue
&si
) {
408 return "StrIssue[" + std::to_string(si
.val
) + "]"; }
411 // test_unregistered_base_implementations
413 // Issues #854/910: incompatible function args when member function/pointer is in unregistered
414 // base class The methods and member pointers below actually resolve to members/pointers in
415 // UnregisteredBase; before this test/fix they would be registered via lambda with a first
416 // argument of an unregistered type, and thus uncallable.
417 py::class_
<RegisteredDerived
>(m
, "RegisteredDerived")
419 .def("do_nothing", &RegisteredDerived::do_nothing
)
420 .def("increase_value", &RegisteredDerived::increase_value
)
421 .def_readwrite("rw_value", &RegisteredDerived::rw_value
)
422 .def_readonly("ro_value", &RegisteredDerived::ro_value
)
423 // These should trigger a static_assert if uncommented
424 //.def_readwrite("fails", &UserType::value) // should trigger a static_assert if uncommented
425 //.def_readonly("fails", &UserType::value) // should trigger a static_assert if uncommented
426 .def_property("rw_value_prop", &RegisteredDerived::get_int
, &RegisteredDerived::set_int
)
427 .def_property_readonly("ro_value_prop", &RegisteredDerived::get_double
)
428 // This one is in the registered class:
429 .def("sum", &RegisteredDerived::sum
)
432 using Adapted
= decltype(py::method_adaptor
<RegisteredDerived
>(&RegisteredDerived::do_nothing
));
433 static_assert(std::is_same
<Adapted
, void (RegisteredDerived::*)() const>::value
, "");
435 // test_custom_caster_destruction
436 // Test that `take_ownership` works on types with a custom type caster when given a pointer
438 // default policy: don't take ownership:
439 m
.def("custom_caster_no_destroy", []() { static auto *dt
= new DestructionTester(); return dt
; });
441 m
.def("custom_caster_destroy", []() { return new DestructionTester(); },
442 py::return_value_policy::take_ownership
); // Takes ownership: destroy when finished
443 m
.def("custom_caster_destroy_const", []() -> const DestructionTester
* { return new DestructionTester(); },
444 py::return_value_policy::take_ownership
); // Likewise (const doesn't inhibit destruction)
445 m
.def("destruction_tester_cstats", &ConstructorStats::get
<DestructionTester
>, py::return_value_policy::reference
);