"example/example-smart-ptr.py" did not exist on "a576e6a8ca5f22f9f9d5f149929637c3337ad086"
test_methods_and_attributes.cpp 23.1 KB
Newer Older
1
/*
Dean Moldovan's avatar
Dean Moldovan committed
2
    tests/test_methods_and_attributes.cpp -- constructors, deconstructors, attribute access,
3
4
5
6
7
8
9
10
    __str__, argument and return value conventions

    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>

    All rights reserved. Use of this source code is governed by a
    BSD-style license that can be found in the LICENSE file.
*/

Dean Moldovan's avatar
Dean Moldovan committed
11
12
#include "pybind11_tests.h"
#include "constructor_stats.h"
13

14
15
16
17
18
#if !defined(PYBIND11_OVERLOAD_CAST)
template <typename... Args>
using overload_cast_ = pybind11::detail::overload_cast_impl<Args...>;
#endif

19
20
class ExampleMandA {
public:
21
22
23
24
25
26
    ExampleMandA() { print_default_created(this); }
    ExampleMandA(int value) : value(value) { print_created(this, value); }
    ExampleMandA(const ExampleMandA &e) : value(e.value) { print_copy_created(this); }
    ExampleMandA(ExampleMandA &&e) : value(e.value) { print_move_created(this); }
    ~ExampleMandA() { print_destroyed(this); }

27
28
29
30
    std::string toString() {
        return "ExampleMandA[value=" + std::to_string(value) + "]";
    }

31
32
    void operator=(const ExampleMandA &e) { print_copy_assigned(this); value = e.value; }
    void operator=(ExampleMandA &&e) { print_move_assigned(this); value = e.value; }
33

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
    void add1(ExampleMandA other) { value += other.value; }         // passing by value
    void add2(ExampleMandA &other) { value += other.value; }        // passing by reference
    void add3(const ExampleMandA &other) { value += other.value; }  // passing by const reference
    void add4(ExampleMandA *other) { value += other->value; }       // passing by pointer
    void add5(const ExampleMandA *other) { value += other->value; } // passing by const pointer

    void add6(int other) { value += other; }                        // passing by value
    void add7(int &other) { value += other; }                       // passing by reference
    void add8(const int &other) { value += other; }                 // passing by const reference
    void add9(int *other) { value += *other; }                      // passing by pointer
    void add10(const int *other) { value += *other; }               // passing by const pointer

    ExampleMandA self1() { return *this; }                          // return by value
    ExampleMandA &self2() { return *this; }                         // return by reference
    const ExampleMandA &self3() { return *this; }                   // return by const reference
    ExampleMandA *self4() { return this; }                          // return by pointer
    const ExampleMandA *self5() { return this; }                    // return by const pointer

    int internal1() { return value; }                               // return by value
    int &internal2() { return value; }                              // return by reference
    const int &internal3() { return value; }                        // return by const reference
    int *internal4() { return &value; }                             // return by pointer
    const int *internal5() { return &value; }                       // return by const pointer

    py::str overloaded()             { return "()"; }
    py::str overloaded(int)          { return "(int)"; }
60
61
62
63
    py::str overloaded(int, float)   { return "(int, float)"; }
    py::str overloaded(float, int)   { return "(float, int)"; }
    py::str overloaded(int, int)     { return "(int, int)"; }
    py::str overloaded(float, float) { return "(float, float)"; }
64
    py::str overloaded(int)          const { return "(int) const"; }
65
66
67
68
    py::str overloaded(int, float)   const { return "(int, float) const"; }
    py::str overloaded(float, int)   const { return "(float, int) const"; }
    py::str overloaded(int, int)     const { return "(int, int) const"; }
    py::str overloaded(float, float) const { return "(float, float) const"; }
69

70
    static py::str overloaded(float) { return "static float"; }
71

72
73
74
    int value = 0;
};

75
76
77
78
79
80
81
82
83
84
85
86
struct TestProperties {
    int value = 1;
    static int static_value;

    int get() const { return value; }
    void set(int v) { value = v; }

    static int static_get() { return static_value; }
    static void static_set(int v) { static_value = v; }
};
int TestProperties::static_value = 1;

87
88
89
90
91
92
struct TestPropertiesOverride : TestProperties {
    int value = 99;
    static int static_value;
};
int TestPropertiesOverride::static_value = 99;

93
struct TestPropRVP {
94
95
96
97
98
99
100
101
102
103
    UserType v1{1};
    UserType v2{1};
    static UserType sv1;
    static UserType sv2;

    const UserType &get1() const { return v1; }
    const UserType &get2() const { return v2; }
    UserType get_rvalue() const { return v2; }
    void set1(int v) { v1.set(v); }
    void set2(int v) { v2.set(v); }
104
};
105
106
UserType TestPropRVP::sv1(1);
UserType TestPropRVP::sv2(1);
107

108
109
110
// py::arg/py::arg_v testing: these arguments just record their argument when invoked
class ArgInspector1 { public: std::string arg = "(default arg inspector 1)"; };
class ArgInspector2 { public: std::string arg = "(default arg inspector 2)"; };
111
class ArgAlwaysConverts { };
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
namespace pybind11 { namespace detail {
template <> struct type_caster<ArgInspector1> {
public:
    PYBIND11_TYPE_CASTER(ArgInspector1, _("ArgInspector1"));

    bool load(handle src, bool convert) {
        value.arg = "loading ArgInspector1 argument " +
            std::string(convert ? "WITH" : "WITHOUT") + " conversion allowed.  "
            "Argument value = " + (std::string) str(src);
        return true;
    }

    static handle cast(const ArgInspector1 &src, return_value_policy, handle) {
        return str(src.arg).release();
    }
};
template <> struct type_caster<ArgInspector2> {
public:
    PYBIND11_TYPE_CASTER(ArgInspector2, _("ArgInspector2"));

    bool load(handle src, bool convert) {
        value.arg = "loading ArgInspector2 argument " +
            std::string(convert ? "WITH" : "WITHOUT") + " conversion allowed.  "
            "Argument value = " + (std::string) str(src);
        return true;
    }

    static handle cast(const ArgInspector2 &src, return_value_policy, handle) {
        return str(src.arg).release();
    }
};
143
144
145
146
147
148
149
150
151
template <> struct type_caster<ArgAlwaysConverts> {
public:
    PYBIND11_TYPE_CASTER(ArgAlwaysConverts, _("ArgAlwaysConverts"));

    bool load(handle, bool convert) {
        return convert;
    }

    static handle cast(const ArgAlwaysConverts &, return_value_policy, handle) {
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
        return py::none().release();
    }
};
}}

// test_custom_caster_destruction
class DestructionTester {
public:
    DestructionTester() { print_default_created(this); }
    ~DestructionTester() { print_destroyed(this); }
    DestructionTester(const DestructionTester &) { print_copy_created(this); }
    DestructionTester(DestructionTester &&) { print_move_created(this); }
    DestructionTester &operator=(const DestructionTester &) { print_copy_assigned(this); return *this; }
    DestructionTester &operator=(DestructionTester &&) { print_move_assigned(this); return *this; }
};
namespace pybind11 { namespace detail {
template <> struct type_caster<DestructionTester> {
    PYBIND11_TYPE_CASTER(DestructionTester, _("DestructionTester"));
    bool load(handle, bool) { return true; }

    static handle cast(const DestructionTester &, return_value_policy, handle) {
        return py::bool_(true).release();
174
175
    }
};
176
177
}}

178
179
180
181
182
183
184
185
// Test None-allowed py::arg argument policy
class NoneTester { public: int answer = 42; };
int none1(const NoneTester &obj) { return obj.answer; }
int none2(NoneTester *obj) { return obj ? obj->answer : -1; }
int none3(std::shared_ptr<NoneTester> &obj) { return obj ? obj->answer : -1; }
int none4(std::shared_ptr<NoneTester> *obj) { return obj && *obj ? (*obj)->answer : -1; }
int none5(std::shared_ptr<NoneTester> obj) { return obj ? obj->answer : -1; }

186
187
188
189
190
191
192
struct StrIssue {
    int val = -1;

    StrIssue() = default;
    StrIssue(int i) : val{i} {}
};

193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
// Issues #854, #910: incompatible function args when member function/pointer is in unregistered base class
class UnregisteredBase {
public:
    void do_nothing() const {}
    void increase_value() { rw_value++; ro_value += 0.25; }
    void set_int(int v) { rw_value = v; }
    int get_int() const { return rw_value; }
    double get_double() const { return ro_value; }
    int rw_value = 42;
    double ro_value = 1.25;
};
class RegisteredDerived : public UnregisteredBase {
public:
    using UnregisteredBase::UnregisteredBase;
    double sum() const { return rw_value + ro_value; }
};

210
211
212
213
214
215
216
217
// Test explicit lvalue ref-qualification
struct RefQualified {
    int value = 0;

    void refQualified(int other) & { value += other; }
    int constRefQualified(int other) const & { return value + other; }
};

218
219
TEST_SUBMODULE(methods_and_attributes, m) {
    // test_methods_and_attributes
220
221
    py::class_<ExampleMandA> emna(m, "ExampleMandA");
    emna.def(py::init<>())
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
        .def(py::init<int>())
        .def(py::init<const ExampleMandA&>())
        .def("add1", &ExampleMandA::add1)
        .def("add2", &ExampleMandA::add2)
        .def("add3", &ExampleMandA::add3)
        .def("add4", &ExampleMandA::add4)
        .def("add5", &ExampleMandA::add5)
        .def("add6", &ExampleMandA::add6)
        .def("add7", &ExampleMandA::add7)
        .def("add8", &ExampleMandA::add8)
        .def("add9", &ExampleMandA::add9)
        .def("add10", &ExampleMandA::add10)
        .def("self1", &ExampleMandA::self1)
        .def("self2", &ExampleMandA::self2)
        .def("self3", &ExampleMandA::self3)
        .def("self4", &ExampleMandA::self4)
        .def("self5", &ExampleMandA::self5)
        .def("internal1", &ExampleMandA::internal1)
        .def("internal2", &ExampleMandA::internal2)
        .def("internal3", &ExampleMandA::internal3)
        .def("internal4", &ExampleMandA::internal4)
        .def("internal5", &ExampleMandA::internal5)
244
#if defined(PYBIND11_OVERLOAD_CAST)
245
246
        .def("overloaded", py::overload_cast<>(&ExampleMandA::overloaded))
        .def("overloaded", py::overload_cast<int>(&ExampleMandA::overloaded))
247
248
249
250
251
        .def("overloaded", py::overload_cast<int,   float>(&ExampleMandA::overloaded))
        .def("overloaded", py::overload_cast<float,   int>(&ExampleMandA::overloaded))
        .def("overloaded", py::overload_cast<int,     int>(&ExampleMandA::overloaded))
        .def("overloaded", py::overload_cast<float, float>(&ExampleMandA::overloaded))
        .def("overloaded_float", py::overload_cast<float, float>(&ExampleMandA::overloaded))
252
        .def("overloaded_const", py::overload_cast<int         >(&ExampleMandA::overloaded, py::const_))
253
254
255
256
        .def("overloaded_const", py::overload_cast<int,   float>(&ExampleMandA::overloaded, py::const_))
        .def("overloaded_const", py::overload_cast<float,   int>(&ExampleMandA::overloaded, py::const_))
        .def("overloaded_const", py::overload_cast<int,     int>(&ExampleMandA::overloaded, py::const_))
        .def("overloaded_const", py::overload_cast<float, float>(&ExampleMandA::overloaded, py::const_))
257
#else
258
259
260
261
        // Use both the traditional static_cast method and the C++11 compatible overload_cast_
        .def("overloaded", overload_cast_<>()(&ExampleMandA::overloaded))
        .def("overloaded", overload_cast_<int>()(&ExampleMandA::overloaded))
        .def("overloaded", overload_cast_<int,   float>()(&ExampleMandA::overloaded))
262
263
264
        .def("overloaded", static_cast<py::str (ExampleMandA::*)(float,   int)>(&ExampleMandA::overloaded))
        .def("overloaded", static_cast<py::str (ExampleMandA::*)(int,     int)>(&ExampleMandA::overloaded))
        .def("overloaded", static_cast<py::str (ExampleMandA::*)(float, float)>(&ExampleMandA::overloaded))
265
266
267
        .def("overloaded_float", overload_cast_<float, float>()(&ExampleMandA::overloaded))
        .def("overloaded_const", overload_cast_<int         >()(&ExampleMandA::overloaded, py::const_))
        .def("overloaded_const", overload_cast_<int,   float>()(&ExampleMandA::overloaded, py::const_))
268
269
270
        .def("overloaded_const", static_cast<py::str (ExampleMandA::*)(float,   int) const>(&ExampleMandA::overloaded))
        .def("overloaded_const", static_cast<py::str (ExampleMandA::*)(int,     int) const>(&ExampleMandA::overloaded))
        .def("overloaded_const", static_cast<py::str (ExampleMandA::*)(float, float) const>(&ExampleMandA::overloaded))
271
#endif
272
        // test_no_mixed_overloads
273
274
        // Raise error if trying to mix static/non-static overloads on the same name:
        .def_static("add_mixed_overloads1", []() {
275
            auto emna = py::reinterpret_borrow<py::class_<ExampleMandA>>(py::module::import("pybind11_tests.methods_and_attributes").attr("ExampleMandA"));
276
            emna.def       ("overload_mixed1", static_cast<py::str (ExampleMandA::*)(int, int)>(&ExampleMandA::overloaded))
277
                .def_static("overload_mixed1", static_cast<py::str (              *)(float   )>(&ExampleMandA::overloaded));
278
279
        })
        .def_static("add_mixed_overloads2", []() {
280
281
            auto emna = py::reinterpret_borrow<py::class_<ExampleMandA>>(py::module::import("pybind11_tests.methods_and_attributes").attr("ExampleMandA"));
            emna.def_static("overload_mixed2", static_cast<py::str (              *)(float   )>(&ExampleMandA::overloaded))
282
283
                .def       ("overload_mixed2", static_cast<py::str (ExampleMandA::*)(int, int)>(&ExampleMandA::overloaded));
        })
284
        .def("__str__", &ExampleMandA::toString)
Wenzel Jakob's avatar
Wenzel Jakob committed
285
        .def_readwrite("value", &ExampleMandA::value);
Dean Moldovan's avatar
Dean Moldovan committed
286

287
    // test_copy_method
288
289
290
    // Issue #443: can't call copied methods in Python 3
    emna.attr("add2b") = emna.attr("add2");

291
    // test_properties, test_static_properties, test_static_cls
292
    py::class_<TestProperties>(m, "TestProperties")
293
294
295
        .def(py::init<>())
        .def_readonly("def_readonly", &TestProperties::value)
        .def_readwrite("def_readwrite", &TestProperties::value)
296
297
298
        .def_property("def_writeonly", nullptr,
                      [](TestProperties& s,int v) { s.value = v; } )
        .def_property("def_property_writeonly", nullptr, &TestProperties::set)
299
300
        .def_property_readonly("def_property_readonly", &TestProperties::get)
        .def_property("def_property", &TestProperties::get, &TestProperties::set)
301
        .def_property("def_property_impossible", nullptr, nullptr)
302
303
        .def_readonly_static("def_readonly_static", &TestProperties::static_value)
        .def_readwrite_static("def_readwrite_static", &TestProperties::static_value)
304
305
        .def_property_static("def_writeonly_static", nullptr,
                             [](py::object, int v) { TestProperties::static_value = v; })
306
307
        .def_property_readonly_static("def_property_readonly_static",
                                      [](py::object) { return TestProperties::static_get(); })
308
309
        .def_property_static("def_property_writeonly_static", nullptr,
                             [](py::object, int v) { return TestProperties::static_set(v); })
310
311
        .def_property_static("def_property_static",
                             [](py::object) { return TestProperties::static_get(); },
312
313
314
315
                             [](py::object, int v) { TestProperties::static_set(v); })
        .def_property_static("static_cls",
                             [](py::object cls) { return cls; },
                             [](py::object cls, py::function f) { f(cls); });
316

317
318
319
320
321
    py::class_<TestPropertiesOverride, TestProperties>(m, "TestPropertiesOverride")
        .def(py::init<>())
        .def_readonly("def_readonly", &TestPropertiesOverride::value)
        .def_readonly_static("def_readonly_static", &TestPropertiesOverride::static_value);

322
323
324
325
    auto static_get1 = [](py::object) -> const UserType & { return TestPropRVP::sv1; };
    auto static_get2 = [](py::object) -> const UserType & { return TestPropRVP::sv2; };
    auto static_set1 = [](py::object, int v) { TestPropRVP::sv1.set(v); };
    auto static_set2 = [](py::object, int v) { TestPropRVP::sv2.set(v); };
326
327
    auto rvp_copy = py::return_value_policy::copy;

328
    // test_property_return_value_policies
329
    py::class_<TestPropRVP>(m, "TestPropRVP")
330
331
332
333
334
335
336
337
338
339
340
341
342
        .def(py::init<>())
        .def_property_readonly("ro_ref", &TestPropRVP::get1)
        .def_property_readonly("ro_copy", &TestPropRVP::get2, rvp_copy)
        .def_property_readonly("ro_func", py::cpp_function(&TestPropRVP::get2, rvp_copy))
        .def_property("rw_ref", &TestPropRVP::get1, &TestPropRVP::set1)
        .def_property("rw_copy", &TestPropRVP::get2, &TestPropRVP::set2, rvp_copy)
        .def_property("rw_func", py::cpp_function(&TestPropRVP::get2, rvp_copy), &TestPropRVP::set2)
        .def_property_readonly_static("static_ro_ref", static_get1)
        .def_property_readonly_static("static_ro_copy", static_get2, rvp_copy)
        .def_property_readonly_static("static_ro_func", py::cpp_function(static_get2, rvp_copy))
        .def_property_static("static_rw_ref", static_get1, static_set1)
        .def_property_static("static_rw_copy", static_get2, static_set2, rvp_copy)
        .def_property_static("static_rw_func", py::cpp_function(static_get2, rvp_copy), static_set2)
343
        // test_property_rvalue_policy
344
        .def_property_readonly("rvalue", &TestPropRVP::get_rvalue)
345
        .def_property_readonly_static("static_rvalue", [](py::object) { return UserType(1); });
346

347
    // test_metaclass_override
348
349
350
351
    struct MetaclassOverride { };
    py::class_<MetaclassOverride>(m, "MetaclassOverride", py::metaclass((PyObject *) &PyType_Type))
        .def_property_readonly_static("readonly", [](py::object) { return 1; });

352
#if !defined(PYPY_VERSION)
353
354
355
356
357
358
    // test_dynamic_attributes
    class DynamicClass {
    public:
        DynamicClass() { print_default_created(this); }
        ~DynamicClass() { print_destroyed(this); }
    };
Dean Moldovan's avatar
Dean Moldovan committed
359
360
    py::class_<DynamicClass>(m, "DynamicClass", py::dynamic_attr())
        .def(py::init());
361

362
    class CppDerivedDynamicClass : public DynamicClass { };
363
364
    py::class_<CppDerivedDynamicClass, DynamicClass>(m, "CppDerivedDynamicClass")
        .def(py::init());
365
#endif
366

367
368
    // test_noconvert_args
    //
369
370
371
    // Test converting.  The ArgAlwaysConverts is just there to make the first no-conversion pass
    // fail so that our call always ends up happening via the second dispatch (the one that allows
    // some conversion).
372
373
    class ArgInspector {
    public:
374
375
        ArgInspector1 f(ArgInspector1 a, ArgAlwaysConverts) { return a; }
        std::string g(ArgInspector1 a, const ArgInspector1 &b, int c, ArgInspector2 *d, ArgAlwaysConverts) {
376
377
            return a.arg + "\n" + b.arg + "\n" + std::to_string(c) + "\n" + d->arg;
        }
378
        static ArgInspector2 h(ArgInspector2 a, ArgAlwaysConverts) { return a; }
379
380
381
    };
    py::class_<ArgInspector>(m, "ArgInspector")
        .def(py::init<>())
382
383
384
        .def("f", &ArgInspector::f, py::arg(), py::arg() = ArgAlwaysConverts())
        .def("g", &ArgInspector::g, "a"_a.noconvert(), "b"_a, "c"_a.noconvert()=13, "d"_a=ArgInspector2(), py::arg() = ArgAlwaysConverts())
        .def_static("h", &ArgInspector::h, py::arg().noconvert(), py::arg() = ArgAlwaysConverts())
385
        ;
386
387
    m.def("arg_inspect_func", [](ArgInspector2 a, ArgInspector1 b, ArgAlwaysConverts) { return a.arg + "\n" + b.arg; },
            py::arg().noconvert(false), py::arg_v(nullptr, ArgInspector1()).noconvert(true), py::arg() = ArgAlwaysConverts());
388
389
390

    m.def("floats_preferred", [](double f) { return 0.5 * f; }, py::arg("f"));
    m.def("floats_only", [](double f) { return 0.5 * f; }, py::arg("f").noconvert());
391
392
    m.def("ints_preferred", [](int i) { return i / 2; }, py::arg("i"));
    m.def("ints_only", [](int i) { return i / 2; }, py::arg("i").noconvert());
393

394
    // test_bad_arg_default
395
    // Issue/PR #648: bad arg default debugging output
396
397
398
399
400
401
#if !defined(NDEBUG)
    m.attr("debug_enabled") = true;
#else
    m.attr("debug_enabled") = false;
#endif
    m.def("bad_arg_def_named", []{
Jason Rhinelander's avatar
Jason Rhinelander committed
402
        auto m = py::module::import("pybind11_tests");
403
        m.def("should_fail", [](int, UnregisteredType) {}, py::arg(), py::arg("a") = UnregisteredType());
404
405
    });
    m.def("bad_arg_def_unnamed", []{
Jason Rhinelander's avatar
Jason Rhinelander committed
406
        auto m = py::module::import("pybind11_tests");
407
        m.def("should_fail", [](int, UnregisteredType) {}, py::arg(), py::arg() = UnregisteredType());
408
    });
409

410
    // test_accepts_none
411
412
413
414
415
416
417
418
419
420
421
422
423
    py::class_<NoneTester, std::shared_ptr<NoneTester>>(m, "NoneTester")
        .def(py::init<>());
    m.def("no_none1", &none1, py::arg().none(false));
    m.def("no_none2", &none2, py::arg().none(false));
    m.def("no_none3", &none3, py::arg().none(false));
    m.def("no_none4", &none4, py::arg().none(false));
    m.def("no_none5", &none5, py::arg().none(false));
    m.def("ok_none1", &none1);
    m.def("ok_none2", &none2, py::arg().none(true));
    m.def("ok_none3", &none3);
    m.def("ok_none4", &none4, py::arg().none(true));
    m.def("ok_none5", &none5);

424
    // test_str_issue
425
426
427
428
429
430
431
    // Issue #283: __str__ called on uninitialized instance when constructor arguments invalid
    py::class_<StrIssue>(m, "StrIssue")
        .def(py::init<int>())
        .def(py::init<>())
        .def("__str__", [](const StrIssue &si) {
            return "StrIssue[" + std::to_string(si.val) + "]"; }
        );
432

433
434
    // test_unregistered_base_implementations
    //
435
436
437
438
439
440
441
442
443
444
445
    // Issues #854/910: incompatible function args when member function/pointer is in unregistered
    // base class The methods and member pointers below actually resolve to members/pointers in
    // UnregisteredBase; before this test/fix they would be registered via lambda with a first
    // argument of an unregistered type, and thus uncallable.
    py::class_<RegisteredDerived>(m, "RegisteredDerived")
        .def(py::init<>())
        .def("do_nothing", &RegisteredDerived::do_nothing)
        .def("increase_value", &RegisteredDerived::increase_value)
        .def_readwrite("rw_value", &RegisteredDerived::rw_value)
        .def_readonly("ro_value", &RegisteredDerived::ro_value)
        // These should trigger a static_assert if uncommented
446
447
        //.def_readwrite("fails", &UserType::value) // should trigger a static_assert if uncommented
        //.def_readonly("fails", &UserType::value) // should trigger a static_assert if uncommented
448
449
450
451
452
453
454
455
        .def_property("rw_value_prop", &RegisteredDerived::get_int, &RegisteredDerived::set_int)
        .def_property_readonly("ro_value_prop", &RegisteredDerived::get_double)
        // This one is in the registered class:
        .def("sum", &RegisteredDerived::sum)
        ;

    using Adapted = decltype(py::method_adaptor<RegisteredDerived>(&RegisteredDerived::do_nothing));
    static_assert(std::is_same<Adapted, void (RegisteredDerived::*)() const>::value, "");
456
457
458
459
460
461
462
463
464
465
466
467

    // test_custom_caster_destruction
    // Test that `take_ownership` works on types with a custom type caster when given a pointer

    // default policy: don't take ownership:
    m.def("custom_caster_no_destroy", []() { static auto *dt = new DestructionTester(); return dt; });

    m.def("custom_caster_destroy", []() { return new DestructionTester(); },
            py::return_value_policy::take_ownership); // Takes ownership: destroy when finished
    m.def("custom_caster_destroy_const", []() -> const DestructionTester * { return new DestructionTester(); },
            py::return_value_policy::take_ownership); // Likewise (const doesn't inhibit destruction)
    m.def("destruction_tester_cstats", &ConstructorStats::get<DestructionTester>, py::return_value_policy::reference);
468
469
470
471
472
473
474

    // test_methods_and_attributes
    py::class_<RefQualified>(m, "RefQualified")
        .def(py::init<>())
        .def_readonly("value", &RefQualified::value)
        .def("refQualified", &RefQualified::refQualified)
        .def("constRefQualified", &RefQualified::constRefQualified);
475
}